Laravel Scout ElasticSearch搜索的基础上,搜索到的关键词加高亮的效果。
参考:
搜索结果高亮
Scout
自定义搜索引擎
App\Services\EsEngine.php1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
namespace App\Services;
use Laravel\Scout\Builder;
use ScoutEngines\Elasticsearch\ElasticsearchEngine;
use Illuminate\Database\Eloquent\Collection;
class EsEngine extends ElasticsearchEngine
{
public function search(Builder $builder)
{
$result = $this->performSearch($builder, array_filter([
'numericFilters' => $this->filters($builder),
'size' => $builder->limit,
]));
return $result;
}
/**
* Perform the given search on the engine.
*
* @param Builder $builder
* @return mixed
*/
protected function performSearch(Builder $builder, array $options = [])
{
//定义查询
$params = [
'index' => $this->index,
'type' => $builder->model->searchableAs(),
'body' => [
'query' => [
'bool' => [
'must' => [
[
'query_string' => [
'query' => "{$builder->query}",
]
]
]
]
],
]
];
/**
* 这里使用了 highlight 的配置
*/
if ($builder->model->searchSettings
&& isset($builder->model->searchSettings['attributesToHighlight'])
) {
$attributes = $builder->model->searchSettings['attributesToHighlight'];
foreach ($attributes as $attribute) {
$params['body']['highlight']['fields'][$attribute] = new \stdClass();
}
}
if (isset($options['from'])) {
$params['body']['from'] = $options['from'];
}
if (isset($options['size'])) {
$params['body']['size'] = $options['size'];
}
if (isset($options['numericFilters']) && count($options['numericFilters'])) {
$params['body']['query']['bool']['must'] = array_merge($params['body']['query']['bool']['must'],
$options['numericFilters']);
}
return $this->elastic->search($params);
}
/**
* Map the given results to instances of the given model.
*
* @param mixed $results
* @param \Illuminate\Database\Eloquent\Model $model
* @return Collection
*/
public function map(Builder $builder, $results, $model)
{
if ($results['hits']['total'] === 0) {
return Collection::make();
}
$keys = collect($results['hits']['hits'])
->pluck('_id')->values()->all();
$models = $model->getScoutModelsByIds(
$builder, $keys
)->keyBy(function ($model) {
return $model->getScoutKey();
});
return collect($results['hits']['hits'])->map(function ($hit) use ($model, $models) {
$one = $models[$hit['_id']];
/*
* 这里返回的数据,如果有 highlight,就把对应的 highlight 设置到对象上面,highlights对应model里定义的属性
*/
if (isset($hit['highlight'])) {
$one->highlights = $hit['highlight'];
}
return $one;
});
}
}
修改Scout的Engine
config/scout.php1
'driver' => env('SCOUT_DRIVER', 'es')
app/Providers/AppServiceProvider.php1
2
3
4
5
6
7
8
9
10
11
12
13public function boot()
{
//
resolve(EngineManager::class)->extend('es', function($app) {
//实例化EsEngine
return new EsEngine(ElasticBuilder::create()
->setHosts(config('scout.elasticsearch.hosts'))
->build(),
config('scout.elasticsearch.index')
);
});
}
添加属性trait
app/Traits/EsSearchable.php
traits的拼写,查错查了好久1
2
3
4
5
6
7
8
9
10
11
12
13namespace App\Traits;
trait EsSearchable
{
//query
public $searchSettings = [
'attributesToHighlight' => [
'*'
]
];
//store highlight results for blade template
public $highlight = [];
}
model中添加 EsSearchabel Trait
App/Models/Topic.php1
2
3
4...
use App\Traits\EsSearchabel;
use EsSearchabel;
...
添加关键词的样式
进入Tinker1
2
3//结果中带有<em></em>标签,对标签设置color属性。
$collection = App\Models\Topic::search("qu")->get();
$collection->first()['highlights']['body][0];