You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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条文档对应需求:

  1. Alice (91) -2
  2. Wendy (92) -1
  3. James (98) 0
  4. Chris (00) 1
  5. Karen (06) 2

补充说明

  • 脚本使用ChronoUnit.YEARS计算年份差,若需更精确的日期差(如包含天数),可替换为ChronoUnit.DAYS并调整脚本逻辑;
  • 双重排序规则确保最接近的文档优先,同时避免差值相同时的排序混乱。

内容的提问来源于stack exchange,提问作者Eva Err

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 12:55:25