首页 > 解决方案 > ElasticSearch 聚合返回整个子对象,而不仅仅是键

问题描述

使用 ElasticSearch 的新手,我们有以下结构索引的文档:

{
    "Id": 1246761,
    "ContentTypeName": "Official Statement",
    "Title": "Official statement Title",    
    "Categories": [
        {
            "Id": 3,
            "Type": 1,
            "Name": "Category A",
            "ParentId": 0
        },
        {
            "Id": 10,
            "Type": 3,
            "Name": "Category B",
            "ParentId": 0
        },
        {
            "Id": 426,
            "Type": 7,
            "Name": "Category C",
            "ParentId": 0
        }
    ]
}

要求是获得与关键字搜索匹配的类别+文档计数的聚合列表。到目前为止,我们的查询如下所示:

GET _search
{
  "query": {
    "match_all": {}
  },
  "size": 0,
  "aggs": {
    "my-agg-name": {
      "terms": {
        "field": "Categories.Id"
      }
    }
  }
}

结果是

{
  "hits" : {
    "total" : {
      "value" : 10000,
      "relation" : "gte"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "my-agg-name" : {
      "doc_count_error_upper_bound" : 23845,
      "sum_other_doc_count" : 1068245,
      "buckets" : [
        {
          "key" : 426,
          "doc_count" : 112651
        },
        {
          "key" : 10,
          "doc_count" : 91146
        },
        
        ....
      ]
    }
  }
}

有没有办法取回整个 Category 对象,而不仅仅是 Id ?或者将类别对象序列化为字符串作为键?

标签: elasticsearch

解决方案


您需要使用嵌套聚合来实现所需的用例

添加具有索引映射、搜索查询和搜索结果的工作示例

索引映射:

{
  "mappings": {
    "properties": {
      "Categories": {
        "type": "nested"
      }
    }
  }
}

搜索查询:

{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "resellers": {
      "nested": {
        "path": "Categories"
      },
      "aggs": {
        "my-agg-name": {
          "terms": {
            "field": "Categories.Id"
          },
          "aggs": {
            "categories-doc": {
              "top_hits": {
                "_source": {
                  "includes": [
                    "Categories.Id",
                    "Categories.Type",
                    "Categories.Name",
                    "Categories.ParentId"
                  ]
                },
                "size": 1
              }
            }
          }
        }
      }
    }
  }
}

搜索结果:

"aggregations": {
    "resellers": {
      "doc_count": 3,
      "my-agg-name": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 0,
        "buckets": [
          {
            "key": 3,                    // note this
            "doc_count": 1,
            "categories-doc": {
              "hits": {
                "total": {
                  "value": 1,
                  "relation": "eq"
                },
                "max_score": 1.0,
                "hits": [
                  {
                    "_index": "65847850",
                    "_type": "_doc",
                    "_id": "1",
                    "_nested": {
                      "field": "Categories",
                      "offset": 0
                    },
                    "_score": 1.0,
                    "_source": {
                      "ParentId": 0,
                      "Type": 1,
                      "Id": 3,                     // note this
                      "Name": "Category A"
                    }
                  }
                ]
              }
            }
          },
          {
            "key": 10,
            "doc_count": 1,
            "categories-doc": {
              "hits": {
                "total": {
                  "value": 1,
                  "relation": "eq"
                },
                "max_score": 1.0,
                "hits": [
                  {
                    "_index": "65847850",
                    "_type": "_doc",
                    "_id": "1",
                    "_nested": {
                      "field": "Categories",
                      "offset": 1
                    },
                    "_score": 1.0,
                    "_source": {
                      "ParentId": 0,
                      "Type": 3,
                      "Id": 10,
                      "Name": "Category B"
                    }
                  }
                ]
              }
            }
          },
          {
            "key": 426,
            "doc_count": 1,
            "categories-doc": {
              "hits": {
                "total": {
                  "value": 1,
                  "relation": "eq"
                },
                "max_score": 1.0,
                "hits": [
                  {
                    "_index": "65847850",
                    "_type": "_doc",
                    "_id": "1",
                    "_nested": {
                      "field": "Categories",
                      "offset": 2
                    },
                    "_score": 1.0,
                    "_source": {
                      "ParentId": 0,
                      "Type": 7,
                      "Id": 426,
                      "Name": "Category C"
                    }
                  }
                ]
              }
            }
          }
        ]
      }
    }
  }

推荐阅读