php在做搜索引擎时,进程要对结果进行筛选,所以我们这里记录一下elasticsearch 条件过滤、排序、高亮实现。在创建索引时如果使用了mapping映射,请将要过滤和排序的字段index设置为true
1.如下:我们的begin_time要作为排序,按照开始时间倒序,price票价我们要作为过滤条件
$params = [
'index' => 'concert',
'include_type_name' => true,
'body' => [
'mappings' => [
'magic' => [
'_source' => [
'enabled' => true
],
'properties' => [
'id' =>[
'type' => 'long'
],
'activity_name' =>[
'type' => 'text'
],
'activity_address' =>[
'type' => 'text'
],
'cover' =>[
'type' => 'text',
'index' => false
],
'activity_time'=>[
'type' => 'date',
'format' => 'yyyy-MM-dd HH:mm:ss',
'index' => false
],
'begin_time'=>[
'type' => 'long', 'index' => true
],
'price' => [
'type' => 'float',
'index' => true
]
]
]
]
]
];
$res = $elasticsearchController->create($params);
2.接下来,我们将数据库数据同步到索引文档
$data = 数据库查询结果
foreach ($data as $k=>$v){
$params['body'][] = [
'index' => [
'_index' => 'concert',
'_type' => 'magic',
'_id' => $v['id']
]
];
$params['body'][] = [
'music_id'=>intval($v['id']),
'cover'=>$v['cover'],
'activity_name' => $v['activity_name'],
'price' => floatval($v['price']),
'activity_time' => $v['activity_time'],
'begin_time' => strtotime($v['activity_time']),
'activity_address' => $v['activity_address'],
'platform' => 1
];
// 每 1000 个文件 停止并批量发送请求
if ($k % 5 == 0) {
$res = $elasticsearchController->bulk($params);
// 删除旧的批量请求
$params = ['body' => []];
// 为了节约内存,在完成时取消批量响应
unset($res);
}
}
// 如果最后一批存在,那么就发送
if (!empty($params['body'])) {
$res = $elasticsearchController->bulk($params);
}
3.搜索实现过滤、排序、高亮
$concertParams = [
'index' => 'concert',
'type' => 'magic',
'from' => 0,
'size' => 3,//限制结果数量
'body' =>[
'query'=>[
'bool'=>[
'must'=>[
['match'=>['activity_name'=>$param['keywords']]],
],
'filter'=>[
[ //这里注意多个筛选条件时,term外面还有一层[]
'term' => [//过滤条件匹配
'platform'=>1
]
],[
'range'=>[//过滤范围取值
'price'=>[
'gte'=>10//大于等于10
]
]
]
]
]
],
'highlight'=>[//高亮
"fields"=>[
"activity_name"=>[
"pre_tags"=>"<b style='color:red'>",
"post_tags"=>"</b>"
]
]
],
'sort'=>[
'begin_time'=>'desc'
]
]
];
$concert = $elasticsearchController->search($concertParams);
ok,搞定!
php写搜索时注意:多个筛选条件时,term、range外面还有一层[],高亮需指定字段,sort排序要和query并列而不是写到query里面!
看看结果
[
{
"_index": "concert",
"_type": "magic",
"_id": "22",
"_score": null,
"_source": {
"music_id": 22,
"cover": "http://qyz-upload-server-public.oss-cn-chengdu.aliyuncs.com/other/jpg/20210508/90Hwp9_1620440629751_%E9%9F%B3%E4%B9%90%E8%8A%82%E5%B0%8F%E7%A8%8B%E5%BA%8F.jpg",
"activity_name": "2020成都星巢音乐节",
"price": 0,
"activity_time": "2021-10-17 14:00:00",
"begin_time": 1634450400,
"activity_address": "成都蔚然花海",
"platform": 3
},
"highlight": {
"activity_name": [
"2020成都星巢<b style='color:red'>音</b><b style='color:red'>乐</b>节"
]
},
"sort": [
1634450400
]
}
]