Return 来自 elasticsearch 聚合的复杂嵌套文档

Return complex nested document from elasticsearch aggregation

我有一个如下所示的文档:

{
...other stuff
"tags": [
          {
            "name": "Asian",
            "key": "cuisine-asian"
          },
          {
            "name": "Gluten Free",
            "key": "cuisine-gluten-free"
          }

我的索引映射如下所示:

tags: {
  type: 'nested',
  properties: {
    name: {
      type: 'text',
    },
    key: {
      type: 'keyword',
  }
}

key 字段保证是唯一的。

我正在尝试return所有"tags"的完整列表。
我当前的查询可以 return 包含关键字段的存储桶列表,但我不知道如何 return 整个 "tag" 对象。

查询:

{
  ...
  body: {
    size: 0,
    aggs: {
      tags: {
        nested: {
          path: 'tags'
        },
        aggs: {
          tag_list: {
            terms: {
              size: 999,
              field: 'tags.key',
            }
          }
        }
      }
    }
  }
}

生成响应:

   "aggregations": {
      "tags": {
        "doc_count": 1708,
        "tag_list": {
          "doc_count_error_upper_bound": 0,
          "sum_other_doc_count": 0,
          "buckets": [
            {
              "key": "cuisine-asian",
              "doc_count": 247
            },
            {
              "key": "cuisine-drinks",
              "doc_count": 112
            },

我希望得到看起来更像下面的东西:

"buckets": [
            {
              "key": "cuisine-asian",
              "name": "Asian",
              "doc_count": 247
            },
            {
              "key": "cuisine-drinks",
              "name": "Drinks",
              "doc_count": 112
            },

如果 matters/helps,doc_count 字段无关紧要 - 我只关心

形式的基数列表
            {
              "key": "cuisine-drinks",
              "name": "Drinks",
            },

干杯!

您可以使用 composite aggregation 在 tag_key 和 tag_name 的组合值上创建存储桶。

复合聚合中after_key用于分页

查询:

{
  "size": 0,
  "aggs": {
    "tag": {
      "nested": {
        "path": "tags"
      },
      "aggs": {
        "tag_list": {
          "composite": {
            "sources": [
              {
                "tags_key": {
                  "terms": {
                    "field": "tags.key"
                  }
                }
              },
              {
                "tags_name": {
                  "terms": {
                    "field": "tags.name.keyword"
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
}

结果:

"aggregations" : {
    "tag" : {
      "doc_count" : 2,
      "tag_list" : {
        "after_key" : {
          "tags_key" : "cuisine-gluten-free",
          "tags_name" : "Gluten Free"
        },
        "buckets" : [
          {
            "key" : {
              "tags_key" : "cuisine-asian",
              "tags_name" : "Asian"
            },
            "doc_count" : 1
          },
          {
            "key" : {
              "tags_key" : "cuisine-gluten-free",
              "tags_name" : "Gluten Free"
            },
            "doc_count" : 1
          }
        ]
      }
    }
  }

或者您可以使用 top_hits 聚合来获取键下的完整文档。 查询:

{
  "size": 0,
  "aggs": {
    "tags": {
      "nested": {
        "path": "tags"
      },
      "aggs": {
        "tag_list": {
          "terms": {
            "size": 999,
            "field": "tags.key"
          },
          "aggs": {
            "docs": {
              "top_hits": {
                "size": 10
              }
            }
          }
        }
      }
    }
  }
}

结果:

"aggregations" : {
    "tags" : {
      "doc_count" : 2,
      "tag_list" : {
        "doc_count_error_upper_bound" : 0,
        "sum_other_doc_count" : 0,
        "buckets" : [
          {
            "key" : "cuisine-asian",
            "doc_count" : 1,
            "docs" : {
              "hits" : {
                "total" : {
                  "value" : 1,
                  "relation" : "eq"
                },
                "max_score" : 1.0,
                "hits" : [
                  {
                    "_index" : "index26",
                    "_type" : "_doc",
                    "_id" : "yMDvAXIB90IHVdbFflZp",
                    "_nested" : {
                      "field" : "tags",
                      "offset" : 0
                    },
                    "_score" : 1.0,
                    "_source" : {
                      "name" : "Asian",
                      "key" : "cuisine-asian"
                    }
                  }
                ]
              }
            }
          },
          {
            "key" : "cuisine-gluten-free",
            "doc_count" : 1,
            "docs" : {
              "hits" : {
                "total" : {
                  "value" : 1,
                  "relation" : "eq"
                },
                "max_score" : 1.0,
                "hits" : [
                  {
                    "_index" : "index26",
                    "_type" : "_doc",
                    "_id" : "yMDvAXIB90IHVdbFflZp",
                    "_nested" : {
                      "field" : "tags",
                      "offset" : 1
                    },
                    "_score" : 1.0,
                    "_source" : {
                      "name" : "Gluten Free",
                      "key" : "cuisine-gluten-free"
                    }
                  }
                ]
              }
            }
          }
        ]
      }
    }
  }
}