Elastic Adapter is an adapter for the official PHP Elasticsearch client. It's designed to simplify basic index and document operations.
The current version of Elastic Adapter has been tested with the following configuration:
If your project uses older Elasticsearch, Laravel, or PHP version check the previous major version of the package.
The library can be installed via Composer:
composer require babenkoivan/elastic-adapter
Elastic Adapter uses babenkoivan/elastic-client as a dependency. To change the client settings you need to publish the configuration file first:
php artisan vendor:publish --provider="Elastic\Client\ServiceProvider"
In the newly created config/elastic.client.php file you can define the default connection name and describe multiple
connections using configuration hashes. Please, refer to
the elastic-client documentation for more details.
\Elastic\Adapter\Indices\IndexManager is used to manipulate indices.
Create an index, either with the default settings and mapping:
$index = new \Elastic\Adapter\Indices\Index('my_index');
$indexManager->create($index);
or configured according to your needs:
$mapping = (new \Elastic\Adapter\Indices\Mapping())
->text('title', [
'boost' => 2,
])
->keyword('tag', [
'null_value' => 'NULL'
])
->geoPoint('location')
->dynamic(true)
->dynamicTemplate('no_doc_values', [
'match_mapping_type' => '*',
'mapping' => [
'type' => '{dynamic_type}',
'doc_values' => false,
],
]);
$settings = (new \Elastic\Adapter\Indices\Settings())
->index([
'number_of_replicas' => 2,
'refresh_interval' => -1
]);
$index = new \Elastic\Adapter\Indices\Index('my_index', $mapping, $settings);
$indexManager->create($index);
Alternatively, you can create an index using raw input:
$mapping = [
'properties' => [
'title' => [
'type' => 'text'
]
]
];
$settings = [
'number_of_replicas' => 2
];
$indexManager->createRaw('my_index', $mapping, $settings);
Delete an index:
$indexManager->drop('my_index');
Update an index mapping using builder:
$mapping = (new \Elastic\Adapter\Indices\Mapping())
->text('title', [
'boost' => 2,
])
->keyword('tag', [
'null_value' => 'NULL'
])
->geoPoint('location');
$indexManager->putMapping('my_index', $mapping);
or using raw input:
$mapping = [
'properties' => [
'title' => [
'type' => 'text'
]
]
];
$indexManager->putMappingRaw('my_index', $mapping);
Update an index settings using builder:
$settings = (new \Elastic\Adapter\Indices\Settings())
->analysis([
'analyzer' => [
'content' => [
'type' => 'custom',
'tokenizer' => 'whitespace'
]
]
]);
$indexManager->putSettings('my_index', $settings);
or using raw input:
$settings = [
'number_of_replicas' => 2
];
$indexManager->putSettingsRaw('my_index', $settings);
Check if an index exists:
$indexManager->exists('my_index');
Open an index:
$indexManager->open('my_index');
Close an index:
$indexManager->close('my_index');
Create an alias:
$alias = new \Elastic\Adapter\Indices\Alias('my_alias', true, [
'term' => [
'user_id' => 12,
],
]);
$indexManager->putAlias('my_index', $alias);
The same with raw input:
$settings = [
'is_write_index' => true,
'filter' => [
'term' => [
'user_id' => 12,
],
],
];
$indexManager->putAliasRaw('my_index', 'my_alias', $settings);
Get index aliases:
$indexManager->getAliases('my_index');
Delete an alias:
$indexManager->deleteAlias('my_index', 'my_alias');
Switch Elasticsearch connection:
$indexManager->connection('my_connection');
\Elastic\Adapter\Documents\DocumentManager is used to manage and search documents.
Add a document to the index:
$documents = collect([
new \Elastic\Adapter\Documents\Document('1', ['title' => 'foo']),
new \Elastic\Adapter\Documents\Document('2', ['title' => 'bar']),
]);
$documentManager->index('my_index', $documents);
There is also an option to refresh index immediately:
$documentManager->index('my_index', $documents, true);
Finally, you can set a custom routing:
$routing = (new \Elastic\Adapter\Documents\Routing())
->add('1', 'value1')
->add('2', 'value2');
$documentManager->index('my_index', $documents, false, $routing);
Remove a document from the index:
$documentIds = ['1', '2'];
$documentManager->delete('my_index', $documentIds);
If you want the index to be refreshed immediately pass true as the third argument:
$documentManager->delete('my_index', $documentIds, true);
You can also set a custom routing:
$routing = (new \Elastic\Adapter\Documents\Routing())
->add('1', 'value1')
->add('2', 'value2');
$documentManager->delete('my_index', $documentIds, false, $routing);
Finally, you can delete documents using query:
$documentManager->deleteByQuery('my_index', ['match_all' => new \stdClass()]);
Search documents in the index:
// configure search parameters
$searchParameters = new \Elastic\Adapter\Search\SearchParameters();
// specify indices to search in
$searchParameters->indices(['my_index1', 'my_index2']);
// define the query
$searchParameters->query([
'match' => [
'message' => 'test'
]
]);
// configure highlighting
$searchParameters->highlight([
'fields' => [
'message' => [
'type' => 'plain',
'fragment_size' => 15,
'number_of_fragments' => 3,
'fragmenter' => 'simple'
]
]
]);
// add suggestions
$searchParameters->suggest([
'message_suggest' => [
'text' => 'test',
'term' => [
'field' => 'message'
]
]
]);
// enable source filtering
$searchParameters->source(['message', 'post_date']);
// collapse fields
$searchParameters->collapse([
'field' => 'user'
]);
// aggregate data
$searchParameters->aggregations([
'max_likes' => [
'max' => [
'field' => 'likes'
]
]
]);
// sort documents
$searchParameters->sort([
['post_date' => ['order' => 'asc']],
'_score'
]);
// rescore documents
$searchParameters->rescore([
'window_size' => 50,
'query' => [
'rescore_query' => [
'match_phrase' => [
'message' => [
'query' => 'the quick brown',
'slop' => 2,
],
],
],
'query_weight' => 0.7,
'rescore_query_weight' => 1.2,
]
]);
// add a post filter
$searchParameters->postFilter([
'term' => [
'cover' => 'hard'
]
]);
// track total hits
$searchParameters->trackTotalHits(true);
// track scores
$searchParameters->trackScores(true);
// script fields
$searchParameters->scriptFields([
'my_doubled_field' => [
'script' => [
'lang' => 'painless',
'source' => 'doc[params.field] * params.multiplier',
'params' => [
'field' => 'my_field',
'multiplier' => 2,
],
],
],
]);
// runtime mappings
$searchParameters->runtimeMappings([
'day_of_week' => [
'type' => 'long',
'script' => [
'lang' => 'painless',
'source' => 'doc[params.field] * params.multiplier',
'params' => [
'field' => 'my_field',
'multiplier' => 2,
],
],
],
]);
// boost indices
$searchParameters->indicesBoost([
['my-alias' => 1.4],
['my-index' => 1.3],
]);
// define the search type
$searchParameters->searchType('query_then_fetch');
// set the preference
$searchParameters->preference('_local');
// use pagination
$searchParameters->from(0)->size(20);
// search after
$searchParameters->pointInTime([
'id' => '46ToAwMDaWR5BXV1',
'keep_alive' => '1m',
]);
$searchParameters->searchAfter([
'2021-05-20T05:30:04.832Z',
4294967298,
]);
// use custom routing
$searchParameters->routing(['user1', 'user2']);
// enable explanation
$searchParameters->explain(true);
// set maximum number of documents to collect for each shard
$searchParameters->terminateAfter(10);
// enable caching
$searchParameters->requestCache(true);
// perform the search and get the result
$searchResult = $documentManager->search($searchParameters);
// get the total number of matching documents
$total = $searchResult->total();
// get the corresponding hits
$hits = $searchResult->hits();
// every hit provides access to the related index name, the score, the document, the highlight and more
// in addition, you can get a raw representation of the hit
foreach ($hits as $hit) {
$indexName = $hit->indexName();
$score = $hit->score();
$document = $hit->document();
$highlight = $hit->highlight();
$innerHits = $hit->innerHits();
$innerHitsTotal = $hit->innerHitsTotal();
$raw = $hit->raw();
// get an explanation
$explanation = $searchResult->explanation();
// every explanation includes a value, a description and details
// it is also possible to get its raw representation
$value = $explanation->value();
$description = $explanation->description();
$details = $explanation->details();
$raw = $explanation->raw();
}
// get suggestions
$suggestions = $searchResult->suggestions();
// get aggregations
$aggregations = $searchResult->aggregations();
Switch Elasticsearch connection:
$documentManager->connection('my_connection');
\Elastic\Adapter\Search\PointInTimeManager is used to control points in time.
Open a point in time:
$pointInTimeId = $pointInTimeManager->open('my_index', '1m');
Close a point in time:
$pointInTimeManager->close($pointInTimeId);
Switch Elasticsearch connection:
$pointInTimeManager->connection('my_connection');
How can I help you explore Laravel packages today?