如何合并两个Elasticsearch查询?含空值与日期范围需求
解决Elasticsearch查询合并的问题
我来帮你搞定这个查询合并的问题!你之前遇到的parsing_exception错误,是因为直接把两个完整的查询对象(a和b)当作子查询塞进must里了——Elasticsearch只认特定类型的查询子句,不接受外层带query字段的完整查询结构。
正确的合并思路
你的需求是满足两个条件中的任意一个:
- 特定手机号 +
date_created_tranx在指定日期范围内 - 特定手机号 +
date_created_tranx为空
这本质是“或”逻辑,用Elasticsearch的bool.should子句就能实现,而且可以把两个条件的公共部分(手机号匹配)抽出来放到must里,避免重复查询,提升性能。
最终的正确查询语句
{ "query": { "bool": { "must": [ { "regexp": { "phone_number_cust": ".*702625.*" } } ], "should": [ { "range": { "date_created_tranx": { "gte": "2019-12-01", "lte": "2020-05-07" } } }, { "bool": { "must_not": [ { "exists": { "field": "date_created_tranx" } } ] } } ], "minimum_should_match": 1 } } }
语句解释
must子句:强制所有返回结果都匹配指定的手机号,这是两个条件的公共要求,不用重复写两次。should子句:包含两个可选条件,只要满足其中一个即可:- 第一个是你原来
a里的日期范围查询 - 第二个是你原来
b里的“date_created_tranx不存在”的查询
- 第一个是你原来
minimum_should_match: 1:确保should里至少有一个条件被满足,完美实现“或”的逻辑。
另一种等价写法(不推荐,重复查询)
如果你不想重构条件,也可以直接把a和b里的bool查询部分放到should里:
{ "query": { "bool": { "should": [ { "bool": { "must": [ { "range": { "date_created_tranx": { "gte": "2019-12-01", "lte": "2020-05-07" } } }, { "regexp": { "phone_number_cust": ".*702625.*" } } ] } }, { "bool": { "must": [{ "regexp": { "phone_number_cust": ".*702625.*" } }], "must_not": [{ "exists": { "field": "date_created_tranx" } } ] } } ], "minimum_should_match": 1 } } }
不过这种方式会重复执行手机号的正则匹配,性能不如第一种写法,所以更推荐第一种方案。
内容的提问来源于stack exchange,提问作者Chinmay Hebbal
相关产品推荐
相关产品推荐

