PHP使用MeiliSearch实现全文检索

简介

MeiliSearch是一个快捷、易用且易部署的全文搜索引擎,支持自定义搜索和索引,支持容错搜索、过滤器和同义词。天生支持中文搜索。同时支持搜索结果词语高亮显示等。相比ElasticSearch,MeiliSearch更加轻量化。
官网地址:http://www.meilisearch.com/

安装

支持多种安装方式,本文采取的是docker的安装方式。
其他安装方式详见官网文档:
https://docs.meilisearch.com/learn/getting_started/installation.html#download-and-launch

docker方式安装:

docker run -it --rm \
    -p 7700:7700 \
    -v $(pwd)/data.ms:/data.ms \
    getmeili/meilisearch

运行命令后,程序将自动安装docker版的MeiliSearch,会在你当前执行命令所在的目录下新建一个data.ms文件夹,用于保存MeiliSearch的数据。

安装好后,访问你的服务器IP:7700,例如 http://127.0.0.1:7700 ,显示如下界面则说明安装成功:

导入文档

官方提供了一个movies.json的测试文件

只需要将该文件中的内容POST到/indexes/:index_uid/documents即可,例如:http://127.0.0.1:7700/indexes/movies/documents

其中movies就代表索引的唯一标识。如果没有创建,POST后,会自动创建。

这里为了简便,使用了POSTMAN来发送POST请求。

发送后,返回的响应的如下:

{
    "taskUid": 0,
    "indexUid": "movies",
    "status": "enqueued",
    "type": "documentAdditionOrUpdate",
    "enqueuedAt": "2021-08-11T09:25:53.000000Z"
}

Meilisearch 中的大多数数据库操作都是异步的。这意味着 API 请求不会被立即处理,而是被添加到队列中并一次处理一个。
使用返回taskUid来检查您的文件的状态:
通过访问http://localhost:7700/tasks/0可以查看响应结果的状态。

导入测试数据后,再次回到http://127.0.0.1:7700,可以体验下MeiliSearch了:

更新文档

例如这里将id为9502的数据的title属性的值改为功夫熊猫

发送后,返回的响应的如下:

{
    "taskUid": 1,
    "indexUid": "movies",
    "status": "enqueued",
    "type": "documentAdditionOrUpdate",
    "enqueuedAt": "2022-08-31T12:16:14.7851537Z"
}

通过访问http://localhost:7700/tasks/1可以查看响应结果的状态。

设置检索的字段

通过GET方式http://127.0.0.1:7700/indexes/movies/settings/searchable-attributes可以查询目前检索的字段,默认为所有字段:*

设置检索的字段:

curl \
  -X POST 'http://localhost:7700/indexes/movies/settings/searchable-attributes' \
  --data '[
      "title",
      "description",
      "genre"
  ]'

检索

最简单的搜索

curl \
  'http://localhost:7700/indexes/movies/search' \
  --data '{ "q": "Batman" }'

只需要POST一个参数:q,值为要检索的词到http://localhost:7700/indexes/movies/search即可。
返回的结果为JSON字段串,格式如下:

{
  "hits": [
    {
      "id": "29751",
      "title": "Batman Unmasked: The Psychology of the Dark Knight",
      "poster": "https://image.tmdb.org/t/p/w1280/jjHu128XLARc2k4cJrblAvZe0HE.jpg",
      "overview": "Delve into the world of Batman and the vigilante justice tha",
      "release_date": "2008-07-15"
    },
    {
      "id": "471474",
      "title": "Batman: Gotham by Gaslight",
      "poster": "https://image.tmdb.org/t/p/w1280/7souLi5zqQCnpZVghaXv0Wowi0y.jpg",
      "overview": "ve Victorian Age Gotham City, Batman begins his war on crime",
      "release_date": "2018-01-12"
    }
    ...
  ],
  "offset": 0,
  "limit": 20,
  "processingTimeMs": 2,
  "query": "botman"
}

更多参数

curl \
  'http://localhost:7700/indexes/movies/search' \
  --data '{ "q": "panda", "offset": 0, "limit": 10 }'

以上代表从0开始,查找10个与关键词panda相关的内容。
更多参数可以查看官方文档:https://docs.meilisearch.com/reference/api/search.html#search-in-an-index-with-post-route

高亮关键词

curl 'http://localhost:7700/indexes/movies/search' \
  --data '{ "q": "shifu", "attributesToHighlight": ["overview"] }'

添加attributesToHighlight参数,设置需要高亮关键词的字段。返回的结果中将多一个_formatted字段,该字段内容为添加了关键词高亮的数组,关键词通过html标签<em>包裹。
返回的格式如下:

{
  "id": "50393",
  "title": "Kung Fu Panda Holiday",
  "poster": "https://image.tmdb.org/t/p/w1280/gp18R42TbSUlw9VnXFqyecm52lq.jpg",
  "overview": "The Winter Feast is Po's favorite holiday. Every year he and his father hang decorations, cook together, and serve noodle soup to the villagers. But this year Shifu informs Po that as Dragon Warrior, it is his duty to host the formal Winter Feast at the Jade Palace. Po is caught between his obligations as the Dragon Warrior and his family traditions: between Shifu and Mr. Ping.",
  "release_date": 1290729600,
  "_formatted": {
    "id": "50393",
    "title": "Kung Fu Panda Holiday",
    "poster": "https://image.tmdb.org/t/p/w1280/gp18R42TbSUlw9VnXFqyecm52lq.jpg",
    "overview": "The Winter Feast is Po's favorite holiday. Every year he and his father hang decorations, cook together, and serve noodle soup to the villagers. But this year <em>Shifu</em> informs Po that as Dragon Warrior, it is his duty to host the formal Winter Feast at the Jade Palace. Po is caught between his obligations as the Dragon Warrior and his family traditions: between <em>Shifu</em> and Mr. Ping.",
    "release_date": 1290729600
  }
}

PHP代码

官方提供了PHP SDK的下载,下载地址:https://github.com/meilisearch/meilisearch-php

如果觉得麻烦,也可以使用下面简易的代码:

$result = search('panda');
var_dump($result);

/**
 * 检索
 * @param $keyword
 * @param int $offset
 * @param int $limit
 * @return mixed
 */
function search($keyword,$offset=0,$limit=20)
{
    $addwhere['q'] = $keyword;
    $addwhere['offset'] = $offset;
    $addwhere['limit'] = $limit;
    $addwhere['attributesToHighlight'] = ['title','description'];
    $result =  curlPost('http://localhost:7700/indexes/movies/search',json_encode($addwhere,JSON_UNESCAPED_UNICODE));
    return json_decode($result,true);
}


function curlPost($url = '', $postData = '', $options = array())
{
    if (is_array($postData)) {
        $postData = http_build_query($postData);
    }
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数
    if (!empty($options)) {
        curl_setopt_array($ch, $options);
    }
    //https请求 不验证证书和host
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    $data = curl_exec($ch);
    curl_close($ch);
    return $data;
}

《PHP使用MeiliSearch实现全文检索》上有5条评论

发表评论

邮箱地址不会被公开。 必填项已用*标注