Skip to content

Dynamic Indices

In certain scenarios, it may be necessary to distribute a model’s data across multiple Elasticsearch indices to optimize performance, manage data volume, or comply with specific data storage requirements. The Laravel-Elasticsearch integration accommodates this need through the support for dynamic indices, allowing a single model to interact with a range of indices following a consistent naming pattern.

Implementing Dynamic Indices

To enable dynamic indexing, include the DynamicIndex trait in your model. This trait provides the necessary functionality to work with dynamic indices.

namespace App\Models;
use PDPhilip\Elasticsearch\Eloquent\DynamicIndex;
use PDPhilip\Elasticsearch\Eloquent\Model;
class PageHit extends Model
{
use DynamicIndex;
protected $connection = 'elasticsearch';
}

In this example, the PageHit model is configured to work with indices that match the pattern page_hits*, enabling operations across all indices starting with page_hits.


Creating Records with Dynamic Indices

$pageHit = new PageHit;
$pageHit->page_id = 4;
$pageHit->ip = $someIp;
// Set the specific index for the new record
$pageHit->setSuffix('_' . date('Y-m-d'));
$pageHit->save();

This pattern ensures that new records are stored in the appropriate index based on your application’s logic, such as using the current date to determine the index name.


Retrieving the Current Record’s Suffix

Each model instance associated with a dynamic index retains knowledge of the specific index it pertains to.

In some cases, you may need to know the suffix for a given record. To retrieve the current record’s index suffix, use the getRecordSuffix method

$indexSuffix = $pageHit->getRecordSuffix(); //returns "_2025-01-01"

Querying Across Dynamic Indices

When querying a model with dynamic indices, the query will span all indices that match the defined pattern, allowing for aggregated data retrieval. This means that you can query your model without specifying the exact index, and the query will automatically search across all matching indices.

// Queries all indices matching "page_hits*"
PageHit::where('page_id', 1)->get();

Retrieve page hits for page_id 1 across all ‘page_hits*’ indices

{
"index": "page_hits*",
"body": {
"query": {
"term": {
"page_id": {
"value": 1
}
}
},
"size": 10000
}
}

Targeting a Specific Index

Use withSuffix() to limit queries to a single dynamic index:

PageHit::withSuffix('_2023-01-01')->where('page_id', 3)->get();

Retrieve page hits for page_id 3 from the page_hits_2023-01-01 index only

{
"index": "page_hits_2023-01-01",
"body": {
"query": {
"term": {
"page_id": {
"value": 3
}
}
},
"size": 10000
}
}