如何在Elasticsearch中按优先级查询多条件数组,每个元素仅返回一个匹配结果?
Elasticsearch 多条件优先级匹配查询需求
现有一组包含id、email_id、name字段的键值对数组,需要编写Elasticsearch查询,让数组中的每个元素仅匹配一个结果,匹配优先级为:id优先,其次是email_id,最后是name(即能匹配到id就返回对应结果,id匹配不到再尝试匹配email_id,以此类推)。
示例输入数组:
[ { "id": 1, "email_id": "xyz@abc", "name": "xyz" }, { "id": 2, "email_id": "xxy@abc", "name": "xxy" } ]
示例数组仅含2个元素,因此查询最多返回2个结果,目前暂未想到单条查询实现的方法,求解决方案。
解决方案
可以通过**bool查询结合dis_max查询**实现单条查询完成需求,核心思路如下:
- 为输入数组的每个元素生成一个
dis_max子查询,包含该元素的id、email_id、name三个匹配条件,通过boost值设置优先级权重(权重越高,优先级越高) - 将所有
dis_max子查询放入bool的should数组,设置minimum_should_match: 1确保至少匹配一个子查询 - 设置
size为输入数组的长度,限制返回结果的最大数量
查询示例(对应上述输入数组)
{ "size": 2, "query": { "bool": { "should": [ { "dis_max": { "queries": [ {"term": {"id": {"value": 1, "boost": 10}}}, {"term": {"email_id": {"value": "xyz@abc", "boost": 5}}}, {"match": {"name": {"query": "xyz", "boost": 1}}} ] } }, { "dis_max": { "queries": [ {"term": {"id": {"value": 2, "boost": 10}}}, {"term": {"email_id": {"value": "xxy@abc", "boost": 5}}}, {"match": {"name": {"query": "xxy", "boost": 1}}} ] } } ], "minimum_should_match": 1 } } }
逻辑说明
- 优先级控制:
id的boost值设为最高(10),只要能匹配到id,该结果得分会远高于email_id或name的匹配,会被优先返回;若id无匹配,则选择email_id的匹配(boost=5);前两者都无匹配时才会匹配name(boost=1) - 单元素单结果:每个
dis_max子查询对应输入数组的一个元素,Elasticsearch会为每个子查询选择得分最高的匹配结果,结合size设置,确保最多返回与输入数组元素数量对应的结果 - 字段适配:如果
id是数值类型,用term查询即可;如果name是分词字段,用match查询更合适,若需精确匹配也可改用term
内容的提问来源于stack exchange,提问作者Mithun MP
相关产品推荐
相关产品推荐

