Elasticsearch技术问题:未知日期范围下,如何查找与参考文档日期最相近的文档
在Elasticsearch中查找与参考文档日期最相近的文档
可以通过脚本排序+脚本字段计算实现未知日期范围下,查找与指定文档日期最相近的文档,以下是针对需求的具体实现:
示例数据集
索引 person 包含以下文档:
- name: Alice,birthday: 01.01.1991
- name: Bobby,birthday: 01.01.1963
- name: Karen,birthday: 01.01.2006
- name: James,birthday: 01.01.1998
- name: Chris,birthday: 01.01.2000
- name: Diana,birthday: 01.01.2022
- name: Wendy,birthday: 01.01.1992
需求
查找与James生日最相近的文档,包含James自身以及他生日之前的2个、之后的2个文档。
实现步骤
1. 获取参考文档(James)的生日值
先执行查询拿到James的生日,后续用于计算日期差:
GET /person/_search { "query": { "term": { "name.keyword": "James" } }, "_source": ["birthday"] }
返回结果可得到James的生日为 01.01.1998。
2. 执行排序查询获取目标文档
通过脚本计算每个文档与James生日的年份差值,按差值绝对值升序排序,同时按生日升序处理差值相同的情况,最后取前5条数据:
GET /person/_search { "query": { "match_all": {} }, "script_fields": { "year_diff": { "script": { "source": "ChronoUnit.YEARS.between(LocalDate.parse(doc['birthday'].value, DateTimeFormatter.ofPattern('dd.MM.yyyy')), LocalDate.parse('01.01.1998', DateTimeFormatter.ofPattern('dd.MM.yyyy')))" } } }, "sort": [ { "_script": { "type": "number", "script": { "source": "Math.abs(ChronoUnit.YEARS.between(LocalDate.parse(doc['birthday'].value, DateTimeFormatter.ofPattern('dd.MM.yyyy')), LocalDate.parse('01.01.1998', DateTimeFormatter.ofPattern('dd.MM.yyyy'))))" }, "order": "asc" } }, { "birthday": "asc" } ], "size": 5 }
预期结果
返回的前5条文档对应需求:
- Alice (91) -2
- Wendy (92) -1
- James (98) 0
- Chris (00) 1
- Karen (06) 2
补充说明
- 脚本使用
ChronoUnit.YEARS计算年份差,若需更精确的日期差(如包含天数),可替换为ChronoUnit.DAYS并调整脚本逻辑; - 双重排序规则确保最接近的文档优先,同时避免差值相同时的排序混乱。
内容的提问来源于stack exchange,提问作者Eva Err
相关产品推荐
相关产品推荐

