如何在OpenSearch中实现嵌套类型的日期范围多条件查询
OpenSearch嵌套文档日期范围查询优化
文档结构
我的OpenSearch文档代表酒店/度假住宿,结构如下:
{ "place": {}, "calendar": [ {"calendar_date": "2024-01-05", "days_available": 1}, {"calendar_date": "2024-01-06", "days_available": 2}, {"calendar_date": "2024-01-07", "days_available": 3} ] }
其中calendar是嵌套类型字段。
查询需求
需要筛选出满足以下条件的文档:给定日期范围m-n(包含首尾)内的所有日期,对应的days_available值均大于指定数值。
原始方案问题
我之前的查询需要为日期范围内的每个日期单独创建嵌套查询,虽然能正常工作,但日期范围大时效率极低:
{ "size": 5, "query": { "bool": { "must": [ { "nested": { "path": "calendar", "query": { "bool": { "must": [ { "range": { "calendar.days_available": { "gt": 0 } } }, { "term": { "calendar.calendar_date": "2024-08-13" } } ] } }, "score_mode": "avg" } }, { "nested": { "path": "calendar", "query": { "bool": { "must": [ { "range": { "calendar.days_available": { "gt": 0 } } }, { "term": { "calendar.calendar_date": "2024-08-14" } } ] } }, "score_mode": "avg" } }, { "nested": { "path": "calendar", "query": { "bool": { "must": [ { "range": { "calendar.days_available": { "gt": 0 } } }, { "term": { "calendar.calendar_date": "2024-08-15" } } ] } }, "score_mode": "avg" } } ] } } }
优化后的查询方案
可以通过单个嵌套范围查询结合min_children和must_not实现高效筛选:
{ "size": 5, "query": { "bool": { "must": [ // 确保日期范围内的所有日期都有对应的calendar记录(数量等于日期天数) { "nested": { "path": "calendar", "query": { "range": { "calendar.calendar_date": { "gte": "2024-08-13", "lte": "2024-08-15" } } }, "score_mode": "avg", "min_children": 3 // 替换为日期范围的天数(如2024-08-13到15共3天) } } ], "must_not": [ // 排除任何在日期范围内存在days_available不满足条件的文档 { "nested": { "path": "calendar", "query": { "bool": { "must": [ { "range": { "calendar.calendar_date": { "gte": "2024-08-13", "lte": "2024-08-15" } } }, { "range": { "calendar.days_available": { "lte": 0 // 替换为你的指定数值阈值 } } } ] } } } } ] } } }
方案说明
min_children作用:确保文档在指定日期范围内的calendar条目数量等于日期天数,保证每个日期都有对应的记录,避免遗漏日期的情况。must_not作用:排查并排除掉任何在目标日期范围内存在days_available不满足要求的文档,确保所有符合日期条件的条目都达标。- 整个查询仅使用2个嵌套查询,无论日期范围多大,结构都保持简洁,大幅提升查询效率。
内容的提问来源于stack exchange,提问作者Avdesh Singh
相关产品推荐
相关产品推荐

