【问题标题】:Elasticsearch query by max date按最大日期进行 Elasticsearch 查询
【发布时间】:2020-10-08 11:08:23
【问题描述】:

我有一个仅附加的索引。每个更改都与日期属性一起保存为新文档。为了获取当前的活动数据,我需要按 ID 对所有实体进行分组,并获取日期最新的实体。应该可以为该日期添加过滤器。我一直在玩聚合,但我被滚动 API 卡住了。

数据示例(注意:id 是 guid,日期是 unix 时间戳,这里使用其他值更清楚)

   {"id": "<entityId_date>", "entityId", 1, "date": "2020-05-10", "value": { <JSON document> } }, 
   {"id": "<entityId_date>", "entityId", 1, "date": "2020-06-10", "value": { <JSON document> } }, 
   {"id": "<entityId_date>", "entityId", 2, "date": "2020-04-10", "value": { <JSON document> } }, 
   {"id": "<entityId_date>", "entityId", 2, "date": "2020-08-10", "value": { <JSON document> } },
   {"id": "<entityId_date>", "entityId", 3, "date": "2020-07-10", "value": { <JSON document> } }

要求的结果:

   {"id": "<entityId_date>", "entityId", 1, "date": "2020-06-10", "value": { <JSON document> } }, 
   {"id": "<entityId_date>", "entityId", 2, "date": "2020-08-10", "value": { <JSON document> } },
   {"id": "<entityId_date>", "entityId", 3, "date": "2020-07-10", "value": { <JSON document> } }

尝试了以下查询:

{
  "size": 0,
  "aggs": {
    "id_aggregate": {
      "terms": { 
          "field": "entityId"
       },
      "aggs": {
        "date_aggregate": {
          "top_hits": {
            "sort": [{
                "date.ticks": {
                    "order": "desc"
                }
            }],
            "size": 1
          }
        }
     }
    }
  }
}

我得到的结果是正确的,但我只得到了前 X 个结果。我可以设置id_aggregate 的大小,但可能有数千个文档。 使用普通的搜索查询,我可以使用 Scroll API,但对于聚合,这是不可能的。

我研究过使用分区,但这对我也没有帮助,因为有时文档很少,有时会加载很多。 (这是一种基本查询,我们执行的所有其他查询都将指定额外的过滤器)。

如何构建一个按最大日期获取文档且可滚动的查询?

【问题讨论】:

    标签: elasticsearch elasticsearch-aggregation


    【解决方案1】:

    您可以使用复合聚合来分页并保留 top_hits 聚合以仅检索最新的文档:

    {
      "size": 0,
      "aggs": {
        "comp_parent": {
          "composite": {
            "sources": [
              {
                "by_id": {
                  "terms": {
                    "field": "entityId"
                  }
                }
              }
            ],
            "size": 10,                          <-- bucket size
            "after": {
              "by_id": "<entityId_date>_xyz"     <-- pagination 'cursor'
            }
          },
          "aggs": {
            "hits": {
              "top_hits": {
                "size": 1,
                "sort": [
                  {
                    "date.ticks": {
                      "order": "desc"
                    }
                  }
                ]
              }
            }
          }
        }
      }
    }
    

    【讨论】:

    • 是的,我正在调查。不幸的是,我们仍然停留在 ES 5.7 上,所以我们无法使用复合 aggs :-(
    • 明白了。您当前的设置是否已经达到某些查询超时或其他限制?
    • 我们有大约一百万个文档。我们并不总是需要全部查询它们,但有时我们需要 100K 文档。这不适合滚动
    • 另外,在我们需要过滤的情况下,ES似乎是先过滤,再聚合。这可能会导致错误的结果:如果旧文档的更改方式不符合过滤条件,我们希望从结果中忽略它,而不是检索旧版本
    • 不确定我是否理解 - 如果您应用时间过滤器,旧版本确实会被忽略。或者你是说你事先不知道你想要什么过滤器?
    猜你喜欢
    • 1970-01-01
    • 2014-08-04
    • 1970-01-01
    • 2019-11-17
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    • 2014-03-10
    • 1970-01-01
    相关资源
    最近更新 更多