Note on MongoDB and the _id field
master_id field is either excluded or renamed within your model's toSearchableArray method. The _id field cannot be part of the searchable data in Elasticsearch.repository·master·Indexed 43 days ago
https://github.com/babenkoivan/elastic-scout-driverAn Elasticsearch driver for Laravel Scout that enables advanced search capabilities using Elasticsearch query string syntax. It allows developers to use mini-language syntax (OR, AND, field scoping) within the search() method and provides tools for managing indices, configuring document refresh behavior, and translating Scout Builder instances into Elasticsearch search parameters.
_id field is either excluded or renamed within your model's toSearchableArray method. The _id field cannot be part of the searchable data in Elasticsearch.By default, the Elastic driver indexes a model even if toSearchableArray() returns an empty array. To prevent this and ensure models are only indexed when they actually have searchable data, override the shouldBeSearchable method in your model.
public function shouldBeSearchable()
{
return count($this->toSearchableArray()) > 0;
}To use Elasticsearch with Laravel Scout, you must install both laravel/scout and babenkoivan/elastic-scout-driver via Composer.
After installation, publish the Scout configuration and update the driver option to elastic in config/scout.php.
# Install Scout first
composer require laravel/scout
# Install the Elastic driver
composer require babenkoivan/elastic-scout-driver
# Publish Scout configuration
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"The driver depends on babenkoivan/elastic-client. To customize connection settings (like host, port, or authentication), publish the client configuration file. The resulting file is config/elastic.client.php.
php artisan vendor:publish --provider="Elastic\Client\ServiceProvider"Set the driver option in config/scout.php to elastic to activate the driver. You can also use the SCOUT_DRIVER environment variable.
// config/scout.php
'driver' => env('SCOUT_DRIVER', 'elastic'),You can control whether documents are indexed immediately by configuring the refresh_documents option in config/elastic.scout_driver.php.
Setting this to true is useful for testing environments where you need search results to be available immediately after indexing. It is false by default.
php artisan vendor:publish --provider="Elastic\ScoutDriver\ServiceProvider"The driver uses Elasticsearch query string syntax wrapped in a bool query. This allows you to use mini-language syntax (like OR, AND, and field scoping) directly within the search() method.
If no query string is provided, the driver performs a match all query while respecting any where constraints.
// Using query string syntax (e.g., title must contain 'Star' OR 'Trek')
$orders = App\Order::search('title:(Star OR Trek)')->get();
// Using match all query with constraints
$orders = App\Order::search()->where('user_id', 1)->get();If you need access to the underlying Elasticsearch response instead of a standard Scout collection, use the raw() method. This returns an instance of the SearchResult class.
$searchResult = App\Order::search('Star Trek')->raw();The Engine class uses a configuration setting to determine whether to refresh documents immediately after indexing or deleting. This is controlled by the refresh_documents key in your Laravel configuration.
Set elastic.scout_driver.refresh_documents to true if you need search results to be immediately available after an update or delete operation, though note that this may impact performance.
// In your config/elastic.php
'scout_driver' => [
'refresh_documents' => true,
],When preparing models for indexing, ensure that the _id key is not present in the array returned by either toSearchableArray() or scoutMetadata(). The DocumentFactory automatically uses the model's Scout key as the document ID. Including _id in the content will cause an UnexpectedValueException to be thrown.
To fix this, check your model's toSearchableArray or scoutMetadata methods and remove any _id keys.
<?php
// Incorrect: This will throw an UnexpectedValueException
public function toSearchableArray()
{
return [
'_id' => $this->id, // REMOVE THIS
'name' => $this->name,
];
}
// Correct: The ID is handled automatically
public function toSearchableArray()
{
return [
'name' => $this->name,
];
}The Engine provides methods to manage the lifecycle of Elasticsearch indices directly.
createIndex($name, array $options = []): Creates a new index. Note that you cannot change the primaryKey via the $options array; doing so will throw an InvalidArgumentException.deleteIndex($name): Removes the specified index from Elasticsearch.flush($model): Deletes all documents within the index associated with the provided model using a match_all query.The SearchParametersFactory::makeFromBuilder method is used to translate a Laravel Scout Builder instance into an Elastic\Adapter\Search\SearchParameters object. This object contains the structured query, indices, sorting, and pagination required by the Elastic adapter.
searchableAs() method.query_string inside a bool.must clause.match_all query.wheres, whereIns, and whereNotIns into Elasticsearch filter clauses.orders to Elasticsearch sort arrays.from is calculated using page and perPage keys in the $options array.size is determined by the perPage key in $options, falling back to the Scout builder's limit.When using Scout's where methods, the following operators are mapped to Elasticsearch DSL:
= $\rightarrow$ term!= $\rightarrow$ bool.must_not with term> $\rightarrow$ range with gt>= $\rightarrow$ range with gte< $\rightarrow$ range with lt<= $\rightarrow$ range with lteuse Elastic\ScoutDriver\Factories\SearchParametersFactory;
use Laravel\Scout\Builder;
$factory = new SearchParametersFactory();
$searchParameters = $factory->makeFromBuilder($scoutBuilder, [
'page' => 1,
'perPage' => 15,
]);