PHP elasticsearch 条件过滤、排序、高亮实现

糜宜民
2023-12-01

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
		]
	}
]

 类似资料: