theme: smartblue highlight: a11y-dark
安装
使用docker安装meilisearch
docker run -it --rm --name meilisearch -v $(pwd)/data:/data -p 7700:7700 getmeili/meilisearch:latest
使用
因为本人擅长的是PHP
开发,所以本文示例都将使用PHP
的meilisearch/meilisearch-php
包演示
其他语言请参考官方文档 meilisearch
以下示例的数据结构为:
[
{
"id": 28,
"name": "轻奢纯棉刺绣水洗四件套",
"sub_name": "轻奢纯棉刺绣水洗四件套卖的真的好,爆款推荐(副标题)",
"cate_id1": 3,
"cate_id2": 26,
"cate_id3": 30,
"cate_id1_name": "男装女装",
"cate_id2_name": "女装",
"cate_id3_name": "T恤",
"brand_id": 1001010,
"brand_name": "品牌名称",
"price": "111.00",
"sales": 200,
"tag_ids": [
1,
2
],
"tags_name": [
"新品",
"爆款"
]
},
{
"id": 29,
"name": "秋冬保暖加厚澳洲羊毛被",
"sub_name": "秋冬保暖加厚澳洲羊毛被卖的真的好,爆款推荐,超级合适(副标题)",
"cate_id1": 2,
"cate_id2": 18,
"cate_id3": 23,
"cate_id1_name": "礼品鲜花",
"cate_id2_name": "鲜花",
"cate_id3_name": "卡通花束",
"brand_id": 1001002,
"brand_name": "品牌名称22",
"price": "36.00",
"sales": 64,
"tag_ids": [
],
"tags_name": [
]
},
初始准备
composer require meilisearch/meilisearch-php
composer require guzzlehttp/guzzle
composer require http-interop/http-factory-guzzle:^1.0
链接meilisearch:成功后我们就可以继续后续操作了
use Meilisearch\Client;
$client = new Client('http://127.0.0.1:7700',"API_KEY");
添加文档
$index = $client->index('goods');//goods是索引名称(index);可以类比为mysql的数据表
// $index->addDocumentsJson("json数组字符串");
//使用数组结构添加
$index->addDocuments([
[
"id" => 1,
"name" => "名称1",
...
],
[
"id" => 2,
"name" => "名称2",
...
]
]);
修改index配置
添加完成后我们需要对索引(index)做一些设置,否则在查询或者排序时会出现错误
$settings = [
//设置允许查询字段,不设置会出现( Message: Attribute `xxx` is not filterable. Available filterable) xxx字段不支持查询的错误
'filterableAttributes' => [
"name",
"sub_name",
"cate_id1",
"cate_id2",
"cate_id3",
"brand_id",
"tag_ids",
"id",
],
//设置允许排序的字段,不设置会出现(Message: Attribute `xxx` is not sortable. Available sortable attributes) xxx字段不支持排序的错误
'sortableAttributes' => [
'price',
'sales',
],
//设置排序优先级
'rankingRules' => [
'sort', //自定义sort优先
'words', //关键词相关度优先
'typo', //错词容忍度
'proximity',
'attribute',
'exactness'
],
];
$index = $index->index('goods');
$index->updateSettings($settings);
搜索
//假设我们要实现mysql的以下效果
//select * from goods where tag_ids in (1,2) and name like "%羊毛衫%" and cate_id1 = 1 ;
//或者
//select * from goods where (tag_ids =1 or tag_ids=2) and name like "%羊毛衫%" and cate_id1 = 1 ;
$filter=[
["cate_id1=1"],
[
["tag_ids=1"],
["tag_ids=2"],
],
];//搜索条件
$query = "羊毛衫";//搜索关键字(模糊搜索字段)
$docs = $client->index('goods')
->search($query, [
'filter' => $filter
]);
var_dump($docs->getHits()); //获取数据
限制返回字段
如果需要限制返回字段则增加attributesToRetrieve
属性(顺序不影响查询相关度),类比mysql的 field字段
即 select id,name,sub_name from goods where (tag_ids =1 or tag_ids=2) and name like "%羊毛衫%" and cate_id1 = 1;
$client->index('goods')
->search($query, [
'filter' => $filter,
"attributesToRetrieve"=>[
'id',
'name',
'sub_name',
],
]);
限制模糊查询的字段
$query字默认会在你配置项的所有字段进行搜索满足的,如果你只想某个或者某几个字段进行模糊搜索,应该使用attributesToSearchOn
属性
例如以下示例就是 只在name和sub_name中模糊查询
$docs = $client->index('goods')
->search($query, [
'filter' => $filter,
"attributesToRetrieve"=>[
'id',
'name',
'sub_name',
],
"attributesToSearchOn"=>[
'name',
'sub_name',
],
]);
var_dump($docs->getHits()); //获取数据
分页
使用limit,offset分页
这种分页方式受限于index配置项(Settings object)中的pagination.maxTotalHits字段的长度
即:当offset偏移量大于了maxTotalHits,则会直接返回空结果,且无法获取当前条件查询下的总条数(totalHits),只能获取一个预估的数据条数(estimatedTotalHits)
$docs = $client->index('goods')
->search($query, [
'filter' => $filter,
"attributesToRetrieve"=>[
'id',
'name',
'sub_name',
],
"attributesToSearchOn"=>[
'name',
'sub_name',
],
"limit"=>20,
"offset"=>0,
]);
//$count = $docs->getTotalHits(); 无法获取
$count = $docs->getEstimatedTotalHits() //预估条数
使用hitsPerPage,page分页
这种模式下可以获取查询总条数(totalHits)
$docs = $client->index('goods')
->search($query, [
'filter' => $filter,
"attributesToRetrieve"=>[
'id',
'name',
'sub_name',
],
"attributesToSearchOn"=>[
'name',
'sub_name',
],
"hitsPerPage" => 20, //分页条数
"page" => 1, //第几页
]);
$count = $docs->getTotalHits(); 总的分页条数
var_dump($docs->getHits()); //获取数据
排序
排序字段在配置项设置sortableAttributes
才可以排序
支持多字段排序 asc升序,desc降序
多个字段排序有优先级,第一个排序条件相同才会排序第二个排序条件,类比mysql的order by
如下示例类比mysql:
select * from goods where name like "%羊毛衫%" order by sales desc,price asc;
$sort = ["sales:desc", "price:asc"]
$docs = $client->index('goods')
->search("羊毛衫", [
'sort' => $sort,
]);
完整查询示例
以下示例类比mysql:
select id,name,sub_name from goods where (tag_ids =1 or tag_ids=2) and name like "%羊毛衫%" and cate_id1 = 1 limit 20,offset 0;
//模糊搜索条件
$query ="羊毛衫";
//搜索条件
$filter=[
["cate_id1=1"],
[
["tag_ids=1"],
["tag_ids=2"],
],
];
$sort = ["sales:desc", "price:asc"]
$docs = $client->index('goods')
->search($query, [
'filter' => $filter, //搜索条件
'sort' => $sort, //排序
"hitsPerPage" => 20, //每页条数
"page" => 1,//第几页
"attributesToRetrieve"=>[ //限制返回数据
'id',
'name',
'sub_name',
],
"attributesToSearchOn"=>[ //限制模糊搜索的字段
"name",
"sub_name",
]
]);
$count = $docs->getTotalHits();
$data = $docs->getHits();