Elasticsearch:如何从嵌套文档聚合到每个主文档?

Elasticsearch: How to aggregate from nested documents up to each main document?

是否有一种语法可以将嵌套文档聚合到每个主文档?例如,在下面的示例中,我将如何找回每支球队最年轻的球员?我正在使用 Elasticsearch 7.10。

PUT sample
{
  "mappings": {
    "dynamic": "strict",
    "properties": {
      "teamId": { "type": "keyword", "index": true, "doc_values": true },
      "members": {
        "type": "nested",
        "properties": {
          "memberId": { "type": "keyword", "index": true, "doc_values": true },
          "age": { "type": "integer", "index": true, "doc_values": true}
        }
      }
    }
  }
}

PUT sample/_doc/1
{
      "teamId" : "A"
    , "members" :
      [
          { "memberId" : "A1" , "age" : "11" }
        , { "memberId" : "A2" , "age" : "21" }
        , { "memberId" : "A3" , "age" : "31" }
      ]                                      
}                                            
                                             
PUT sample/_doc/2                            
{                                            
      "teamId" : "B"                         
    , "members" :                            
      [                                      
          { "memberId" : "B1" , "age" : "12" }
        , { "memberId" : "B2" , "age" : "22" }
        , { "memberId" : "B3" , "age" : "32" }
        , { "memberId" : "B4" , "age" : "42" }
      ]                                      
}                                            
                                             
                                             
PUT sample/_doc/3                            
{                                            
      "teamId" : "C"                         
    , "members" :                            
      [                                      
          { "memberId" : "C1" , "age" : "13" }
        , { "memberId" : "C2" , "age" : "23" }
        , { "memberId" : "C3" , "age" : "33" }
      ]
}

您可以使用 nested aggregation with top hits aggregation,下面是适用于您的示例数据的有效查询。

{
    "size": 0,
    "aggs": {
        "teams": {
            "terms": {
                "field": "teamId"
            },
            "aggs": {
                "members": {
                    "nested": {
                        "path": "members"
                    },
                    "aggs": {
                        "min_age_player": {
                            "top_hits": {
                                "sort": [
                                    {
                                        "members.age": {
                                            "order": "asc"
                                        }
                                    }
                                ],
                                "_source": {
                                    "includes": [
                                        "members.memberId",
                                        "members.age"
                                    ]
                                },
                                "size": 1
                            }
                        }
                    }
                }
            }
        }
    }
}