(x)# 从数据库中读取数据导入 Meilisearch
php artisan scout:import "App\Models\District"
(x)# 删除索引中的所有数据
php artisan scout:flush "App\Models\District"
验证搜索结果⌗
$items = District::search('东京')->get();
结果发现查询出来的数据中无法获取到一些 Meilisearch 的高亮信息,于是看了一下 SQL 的 Log,发现就是请求了 Meilisearch search API,然后根据所得的结果,将 ID 列表作为 whereIn
的条件查询出数据库中的模型。
这样的话我们还得自己实现匹配字词的高亮,但是这样会有个问题就是例如我搜索的关键词是东京
,PHP 无法通过这两个字符去替换東京都
中的東京
。
直接调用 RESTful API⌗
尝试过使用 Laravel Scout 的搜索功能,发现无法满足高度自定义的需求,那么只能自己手动处理请求逻辑了。
curl --location --request POST 'http://localhost:7700/indexes/district/search' \
--header 'Authorization: Bearer masterKey' \
--header 'Content-Type: application/json' \
--data-raw '{"q":"东京","matches":true,"limit":10,"attributesToRetrieve":["code","fullname","spelling"],"attributesToHighlight":["fullname"]}'
"matches": true,
"attributesToRetrieve": ["code", "fullname"],
"attributesToHighlight": ["fullname"]
q: 搜索的关键词
limit: 限制响应条数
matches: 响应体是否包含 _matchesInfo
attributesToRetrieve: 设置响应体重包含的字段
attributesToHighlight: 设置需要高亮显示的的字段,用于前段渲染
响应的结果:
"hits": [
"fullname": "東京都",
"code": "13",
"_formatted": {
"fullname": "<em>東京都</em>",
"code": "13"
"_matchesInfo": {
"fullname": [
"start": 0,
"length": 2
"fullname": "東京都千代田区",
"code": "13101",
"_formatted": {
"fullname": "<em>東京都</em>千代田区",
"code": "13101"
"_matchesInfo": {
"fullname": [
"start": 0,
"length": 2
"nbHits": 43,
"exhaustiveNbHits": false,
"query": "东京",
"limit": 2,
"offset": 0,
"processingTimeMs": 1
只要将这些数据返回给前端,由前端对 <em>
标签进行着色渲染,就可以实现高亮了。
索引的相关设置⌗
到这里就完了吗?并没有,在我们的业务中还希望对某个字段进行排序,但是我尝试在搜索的 API 中使用 sort 进行排序,得到的结果总是错误。
经过仔细的阅读 Meilisearch 官方的文档,无发现索引可以有如下几项设置:
Displayed attributes: 属性的可见性设置;
Distinct attribute: 设置相同属性时用于过滤的字段,可以参考官方文档给出的例子;
Filterable attributes: 可过滤的字段设置,默认是 ‘’;例如,数据中存在状态字段,需要通过状态过滤是否展示,可以通过这个设置来实现;
Ranking rules: 设置搜索引擎的权重,默认的是:“words”,“typo”,“proximity”,“attribute”,“sort”,“exactness”,“release_date:desc”;
Searchable attributes: 设置可搜索的字段,默认是 ‘*’;例如,如果有些字段用于排序,比如价格,但不希望被搜索可以使用这个设置将价格字段排除;
Sortable attributes: 设置可排序的字段,例如价格等字段;
Stop-words: 设置不可搜素的词,例如一些没有任何意义的介词、代词等;
Synonyms: 设置同义词
通过这些设置基本上能瞒住绝大部分的业务需求,请求速度上确实都是毫秒级响应,当然目前数据量也不是很大,性能还有待日后观察。
文档更新注意事项⌗
如果在对模型做 UPDATE
操作的时候,一定要将模型的 toSearchableArray
方法中定义的字段在查询的时候 SELECT
出来,否则会导致这个属性更新到 Meilisearch 中的值是 null
!
Dashboard⌗
在管理 Meilisearch 的时候发现总是通过 Postman 或者 cURL 挺麻烦的,后来发现 Meilisearch 自带了一个简单的 Mini Dashboard。
当 MEILI_ENV
为 production
时不可用!
这个不需要自己打包和部署,当 Meilisearch 服务启动后,可以通过浏览器直接访问,就会得到如下页面:
这里输入前面章节的获取 API Keys,然后就可以查看所有的索引,以及在索引下测试搜索功能。
Meilisearch 确实很小巧,也很强大,后面如果有遇到坑也会继续记录和分享,最近有看到一个基于 C++ 开发的搜索引擎——Typesense。又有折腾的素材了!
I hope this is helpful, Happy hacking…