如何自定义Scout+Meilisearch的搜索结果?
解决方案
1. 模型中返回所有需要的字段(含附加展示字段)
在你的Eloquent模型里,toSearchableArray要返回所有同步到Meilisearch的字段,包括仅用于展示的url、thumbnail_url这类附加字段——后续会通过配置让它们不参与搜索索引。
示例代码(Laravel模型):
public function toSearchableArray() { $array = $this->toArray(); // 追加仅用于展示的附加字段 $array['url'] = route('seed.show', $this); $array['thumbnail_url'] = $this->getThumbnailUrl(); // 保留核心搜索字段的同时,带上附加字段 return $array; }
2. 配置Meilisearch的索引规则
通过配置区分可搜索字段(参与关键词匹配)和仅展示字段(不参与索引但返回结果),两种方式可选:
方式一:用Scout内置方法(推荐)
在模型里添加configureSearchableFields方法,指定仅核心字段参与搜索:
public function configureSearchableFields(): array { // 这里只放需要参与搜索匹配的字段,比如标题、描述 return ['title', 'description']; }
这个方法会自动设置Meilisearch的searchableAttributes,而displayedAttributes默认包含所有同步字段,所以附加字段会自动出现在搜索结果里,且不参与索引。
方式二:手动配置索引
如果需要更精细控制返回字段,可通过代码调用Meilisearch API设置:
// 可在Artisan命令或服务提供者中执行 use Laravel\Scout\Searchable; $model = new YourSeedModel(); $indexName = $model->searchableAs(); // 获取Meilisearch客户端 $meilisearchClient = app('scout')->engine()->getClient(); // 更新索引设置 $meilisearchClient->index($indexName)->updateSettings([ 'searchableAttributes' => ['title', 'description'], // 仅核心字段参与搜索 'displayedAttributes' => ['id', 'title', 'description', 'url', 'thumbnail_url'], // 明确指定返回字段 ]);
3. 前端直接使用返回字段
你的现有前端代码无需改动,response.hits里已经包含url和thumbnail_url,直接在build_search_results_menu里调用即可:
function build_search_results_menu(hits) { hits.forEach(hit => { // 直接使用附加字段 const link = hit.url; const thumbnail = hit.thumbnail_url; // 渲染到页面的逻辑... }); }
核心逻辑说明
searchableAttributes:决定哪些字段被Meilisearch用来构建搜索索引,只有这里的字段会参与关键词匹配。displayedAttributes:控制搜索结果返回哪些字段,默认包含所有同步到索引的字段,因此只要附加字段被同步且不在searchableAttributes中,就只会出现在结果里,不会影响搜索匹配。
所有数据处理都在服务器端完成,前端只需要直接使用返回的字段即可。
内容的提问来源于stack exchange,提问作者Luca Reghellin
相关产品推荐
相关产品推荐

