每个类别的最新文档?

时间:2018-05-29 15:57:07

标签: elasticsearch kibana elastic-stack

我在ElasticSearch中有以下结构的文档:

{
    "created_on": [timestamp],
    "source_id": [a string ID for the source],
    "type": [a term],
    ... other fields
}

显然,我可以在Kibana中选择这些文档,在"发现"中显示它们,生成(例如)显示类型术语的饼图,等等。

但是,我已经给出的要求是仅使用每个source_id的最新文档。

我尝试过的方法是按照source_id将文档映射到一个存储桶中,然后对于每个存储桶,使用最新的created_on删除除文档以外的所有文件。

但是,当我使用terms聚合器时,结果只包含计数,而不是我可以进一步处理的整个文档:

"aggs" : {
    "sources" : {
        "terms" : { "field" : "source_id" }
    }
}

如何进行此查询?

1 个答案:

答案 0 :(得分:1)

如果我理解了您正在尝试做的事情,那么实现这一目标的一种方法是使用下的 top_hits 聚合术语聚合,对于按照您希望的任何条件对其父聚合的每个桶进行分组结果非常有用。按照您的示例,您可以执行类似

的操作
{
  "aggs": {
    "by_source_id": {
      "terms": {
        "field": "source_id"
      },
      "aggs": {
        "most_recent": {
          "top_hits": {
            "sort": {
              "created_on": "desc"
            },
            "size": 1
          }
        }
      }
    }
  }
}

所以你按照source_id进行分组,这将为每个创建一个存储桶,然后根据top_hits agg中设置的排序标准获得每个存储桶的最高命中,在这种情况下 created_on 字段。

你应该期待的结果就像是

....

"buckets": [
        {
          "key": 3,
          "doc_count": 2,
          "most_recent": {
            "hits": {
              "total": 2,
              "max_score": null,
              "hits": [
                {
                  "_index": "so_sample02",
                  "_type": "items",
                  "_id": "2",
                  "_score": null,
                  "_source": {
                    "created_on": "2018-05-01 07:00:01",
                    "source_id": 3,
                    "type": "a"
                  },
                  "sort": [
                    1525158001000
                  ]
                }
              ]
            }
          }
        },
        {
          "key": 5,
          "doc_count": 2, .... and so on

请注意,在 most_recent 中,我们获得了相应的匹配。您还可以通过在 top_hits agg "includes": ["fieldA", "fieldB" .. and so on]

中指定来限制返回的字段数量

希望有所帮助。