文档列表中关键字桶中的文档计数作为 Elasticsearch 中的聚合

Document Count in keyword buckets from list in document as aggregation in Elasticsearch

情况:

我是 Elasticsearch 的新手,无法全神贯注地思考如何使用聚合来获取我需要的东西。

我有以下结构的文档:

{
    ...
    "authors" : [
      {
        "name" : "Bob",
        "@type" : "Person"
      }
    ],
    "resort": "Politics",
    ...
}

我想使用聚合来获取每位作者的文档数。由于某些文档可能有不止一位作者,因此这些文档应该针对每个作者单独计算。

我试过的:

由于 terms 聚合与 resort 字段一起使用,我尝试将其与 authors 或内部的 name 字段一起使用,但始终没有任何桶。为此,我使用了以下 curl 请求:

curl -X POST 'localhost:9200/news/_doc/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "_source": false,
  "aggs": {
    "author_agg": { "terms": {"field": "authors.keyword" } }
  }
}'

我得出结论,terms 聚合不适用于列表中包含的字段。

接下来我想到了 nested 聚合,但是文档说,它是一个

single bucket aggregation

所以不是我要搜索的内容。因为我 运行 没有想法,所以我尝试了它,但是出现了错误

"type" : "aggregation_execution_exception",
"reason" : "[nested] nested path [authors] is not nested"

我找到了 this answer 并尝试将其用于我的数据。我有以下要求:

curl -X GET "localhost:9200/news/_search?pretty" -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "nest": {
      "nested": {
        "path": "authors"
      },
      "aggs": {
        "authorname": {
          "terms" : {
            "field": "name.keyword"
          }
        }
      }
    }
  }
}'

这给了我错误

"type" : "aggregation_execution_exception",
"reason" : "[nested] nested path [authors] is not nested"

我搜索了如何使用映射嵌套我的路径,但我找不到如何实现它。我什至不知道,这是否真的有意义。

那么如何根据位于文档中列表元素中的键将文档聚合到桶中?

也许这个问题已经在其他地方得到了回答,但是我无法以正确的方式陈述我的问题,因为我仍然对所有新信息感到困惑。提前感谢您的帮助。

我终于解决了我的问题:

获得 authors 键映射 nested 的想法是完全正确的。但不幸的是,Elasticsearch 不允许您直接将类型从 un-nested 更改为 nested,因为此键中的所有项目也必须被索引。所以你必须走下面的路:

  1. 使用自定义映射创建新索引。在这里,我们进入文档类型 _doc,进入它的属性,然后进入文档字段 authors。我们将 type 设置为 nested.

~

curl -X PUT "localhost:9200/new_index?pretty" -H 'Content-Type: application/json' -d'
{
  "mappings": {
    "_doc" : {
      "properties" : {
        "authors": { "type": "nested" }
      }
    }
  }
}'
  1. 然后我们重新索引我们的数据集并将目标设置为我们新创建的索引。这会将旧索引中的数据索引到新索引中,本质上是复制纯数据,但采用新映射(因为设置和映射不会以这种方式复制)。

~

curl -X POST "localhost:9200/_reindex" -H 'Content-Type: application/json' -d'
{
  "source": {
    "index": "old_index"
  },
  "dest": {
    "index": "new_index"
  }
}'

现在我们可以在此处进行 nested 聚合,根据作者将文档分类到桶中:

curl -X GET 'localhost:9200/new_index/_doc/_search?pretty' -H 'Content-Type: application/json' -d'
{
  "size": 0,
  "aggs": {
    "authors": {
      "nested": {
        "path": "authors"
      },
      "aggs": {
        "authors_by_name": {
          "terms": { "field": "authors.name.keyword" }
        }
      }
    }
  }
}'

直到现在我还不知道如何重命名索引,但您肯定可以简单地删除旧索引,然后按照描述的过程使用旧索引的名称创建另一个新索引,但使用自定义映射。