Elasticsearch中如何按传入的ID数组顺序实现自定义排序
Elasticsearch 按传入ID数组顺序返回查询结果的实现方法
Elasticsearch 默认查询结果按相关性得分排序,即便使用terms查询传入指定ID数组,返回结果的顺序也不会和传入顺序保持一致。可以通过以下两种成熟方案实现顺序匹配:
方案1:脚本排序(最常用)
通过内置脚本获取每个ID在传入数组中的索引位置,按索引升序排序即可完全匹配传入顺序,代码示例如下:
GET /你的产品索引名/_search { "query": { "terms": { "product_id": [101, 102, 103] } }, "sort": [ { "_script": { "type": "number", "script": { "source": "params.id_order.indexOf(doc['product_id'].value)", "params": { "id_order": [101, 102, 103] } }, "order": "asc" } } ] }
注意事项:
- 要保证
product_id字段的类型和传入数组元素类型一致,数值类型/keyword类型都可以直接使用 - 该方案在ID数组长度小于1000时性能表现优异,适合绝大多数业务场景
方案2:权重自定义排序(无需开启脚本权限)
如果你的Elasticsearch集群禁用了inline脚本,可以通过function_score给每个ID设置对应权重,按权重降序排序实现顺序匹配,代码示例如下:
GET /你的产品索引名/_search { "query": { "function_score": { "query": { "terms": { "product_id": [101, 102, 103] } }, "functions": [ {"filter": {"term": {"product_id": 101}}, "weight": 3}, {"filter": {"term": {"product_id": 102}}, "weight": 2}, {"filter": {"term": {"product_id": 103}}, "weight": 1} ], "score_mode": "first", "boost_mode": "replace" } }, "sort": [{"_score": "desc"}] }
注意事项:
- 传入ID数组越长,查询语句的
functions段会越长,建议ID数组长度不超过500时使用该方案 - 无需开启脚本权限,安全性更高,适合有严格集群安全配置的场景
内容的提问来源于stack exchange,提问作者Sahil Kumar
相关产品推荐
相关产品推荐

