-
-
Notifications
You must be signed in to change notification settings - Fork 117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Question] how to include custom attributes in Eloquent model of search results #149
Comments
Two options: Eloquent accessorhttps://laravel.com/docs/8.x/eloquent-mutators#defining-an-accessor When you can generate / build up the data again on runtime, just do so with an accessor in an Eloquent model. Now you have the data again from the model. Implement your own EloquentHitsIteratorAggregateOr, you enrich the model with your own I use this to include the class EloquentHitsIteratorAggregate implements IteratorAggregate
{
/**
* @var array
*/
private $results;
/**
* @var callable|null
*/
private $callback;
/**
* @param array $results
* @param callable|null $callback
*/
public function __construct(array $results, callable $callback = null)
{
$this->results = $results;
$this->callback = $callback;
}
/**
* @inheritDoc
*/
public function getIterator()
{
if (! $this->results['hits']['total']) {
return new \ArrayIterator(collect());
}
/** @var Collection $models */
$models = collect($this->results['hits']['hits'])->groupBy('_source.__class_name')
->map(function ($results, $class) {
$model = new $class;
$builder = new Builder($model, '');
if (!empty($this->callback)) {
$builder->query($this->callback);
}
/* @var Searchable $model */
return $model->getScoutModelsByIds(
$builder, $results->pluck('_id')->all()
);
})
->flatten()->keyBy(function ($model) {
return get_class($model).'::'.$model->getScoutKey();
});
/** @var Collection $hits */
$hits = collect($this->results['hits']['hits'])->map(function ($hit) use ($models) {
$key = $hit['_source']['__class_name'].'::'.$hit['_id'];
if (!isset($models[$key])) {
return null;
}
$model = $models[$key];
// Enrich the model with data from Elasticsearch
$model->_score = $hit['_score'];
$model->_highlight = $hit['highlight'] ?? null;
return $model;
})->filter()->all();
return new \ArrayIterator($hits);
}
} |
PS. You can implement your own class by binding it in the ioc. This can be done in $this->app->bind(
'Matchish\ScoutElasticSearch\ElasticSearch\HitsIteratorAggregate',
'App\Elasticsearch\EloquentHitsIteratorAggregate'
); |
Great, thanks for the extensive reply @ametad! I've been able to add the required fields, thanks! |
Does anyone know how to include custom attributes from the index into the model when returning search results?
I've added custom fields in the index using
toSearchableArray
and these are showing up when returning the raw results. However, when I use the->get()
, the custom fields are not included in the model objects (as they are not in the underlying database table), and I can't seem to find out how to include them.The text was updated successfully, but these errors were encountered: