在弹性搜索中,如何获取嵌套字段的文档最大值?

in elastic search, how can get document max value for nested field?

是我的映射。

"script": {
    "type": "nested",
    "properties": {
        "name": {
            "type": "keyword"
        },
        "age": {
            "type": "integer"
        }
    }
}

和下面的示例文档

PUT /btest/_create/1
{
  "script": [
    {
      "name": "john",
      "age": 14
    }
  ]
}

PUT /btest/_create/2
{
  "script": [
    {
      "name": "tt",
      "age": 14
    },
    {
      "name": "jj",
      "age": 17
    },
    {
      "name": "tim",
      "age": 34
    }
  ]
}

PUT /btest/_create/3
{
  "script": [
    {
      "name": "john",
      "age": 42
    },
    {
      "name": "jj",
      "age": 12
    }
  ]
}

并使用最大聚合来获取最大年龄:

GET /btest/_search
{
  "query": {
    "nested": {
      "path": "script",
      "query": {
        "match": {
          "script.name": "john"
        }
      }
    }
  },
  "aggs": {
    "age": {
      "nested": {
        "path": "script"
      },
      "aggs": {
        "script_age": {
          "filter": {
            "match": {
              "script.name": "john"
            }
          },
          "aggs": {
            "length": {
              "max": {
                "field": "script.age"
              }
            }
          }
        }
      }
    }
  }
}

但它 returns 全部匹配 "script.name": "john".

我只想获取文档的最大年龄 john.

我应该使用聚合来获取这个文档吗?

或者有没有一种方法可以使用类似于 max 的查询而不对嵌套字段进行聚合?

根据您的要求,您只需要获取与名称 john 匹配的那些文档。这可以在查询部分使用 nested query 和匹配查询来实现。

现在,要获取具有 max-age(名称为 john)的文档,您可以在 script.age 字段上执行 top hits aggregationsort

{
    "size": 0,
    "query": {
        "nested": {
            "path": "script",
            "query": {
                "match": {
                    "script.name": "john"
                }
            }
        }
    },
    "aggs": {
        "nested-agg": {
            "nested": {
                "path": "script"
            },
            "aggs": {
                "by_age": {
                    "top_hits": {
                        "sort": [
                            {
                                "script.age": {
                                    "order": "desc"
                                }
                            }
                        ],
                        "size": 1
                    }
                }
            }
        }
    }
}

搜索响应将是

"aggregations": {
        "nested-agg": {
            "doc_count": 3,
            "by_age": {
                "hits": {
                    "total": {
                        "value": 3,
                        "relation": "eq"
                    },
                    "max_score": null,
                    "hits": [
                        {
                            "_index": "71081556",
                            "_type": "_doc",
                            "_id": "3",
                            "_nested": {
                                "field": "script",
                                "offset": 0
                            },
                            "_score": null,
                            "_source": {
                                "name": "john",
                                "age": 42
                            },
                            "sort": [
                                42
                            ]
                        }
                    ]
                }
            }
        }
    }

选项 2

您可以使用 sort with the nested query, 来获取具有最大年龄

的文档
{
    "size": 1,
    "sort": [
        {
            "script.age": {
                "order": "desc",
                "nested": {
                    "path": "script",
                    "filter": {
                        "term": {
                            "script.name": "john"
                        }
                    }
                }
            }
        }
    ]
}

但在这种情况下,响应包含整个文档,而不仅仅是匹配的文档

"hits": [
            {
                "_index": "71081556",
                "_type": "_doc",
                "_id": "3",
                "_score": null,
                "_source": {
                    "script": [
                        {
                            "name": "john",
                            "age": 42
                        },
                        {
                            "name": "jj",
                            "age": 12
                        }
                    ]
                },
                "sort": [
                    42
                ]
            }
        ]