gpt4 book ai didi

elasticsearch - 在Elasticsearch中,如何执行嵌套子聚合?

转载 作者:行者123 更新时间:2023-12-02 23:53:00 25 4
gpt4 key购买 nike

在Kibana中,我如下创建索引:

PUT cars
{
"mappings":{
"_doc":{
"properties":{
"metadata":{
"type":"nested",
"properties":{
"str_value":{
"type":"keyword"
}
}
}
}
}
}
}

然后,我插入三个记录:
POST /cars/_doc/1
{
"metadata": [
{
"key": "model",
"str_value": "Ford"
},
{
"key": "price",
"int_value": 1000
}
]
}
PUT /cars/_doc/2
{
"metadata": [
{
"key": "model",
"str_value": "Ford"
},
{
"key": "price",
"int_value": 2000
}
]
}
PUT /cars/_doc/3
{
"metadata": [
{
"key": "model",
"str_value": "Holden"
},
{
"key": "price",
"int_value": 2500
}
]
}

模式有点不合常规,但是我以此方式设计了索引,以避免映射爆炸:

https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html

我想做的就是得到我所有的汽车模型,以及这些模型的价格之和,即福特3000美元,霍顿2500美元。到目前为止,我有:
GET /cars/_search
{
"aggs":{
"metadata":{
"nested":{
"path":"metadata"
},
"aggs":{
"model_filter":{
"filter":{
"term":{
"metadata.key":"model"
}
},
"aggs":{
"model_counter":{
"terms":{
"field":"metadata.str_value",
"size":1000
}
}
}
}
}
}
}
}

这使我了解其中的一部分,因为它返回了汽车模型和文件计数:
  "aggregations": {
"metadata": {
"doc_count": 6,
"model_filter": {
"doc_count": 3,
"model_counter": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "Ford",
"doc_count": 2
},
{
"key": "Holden",
"doc_count": 1
}
]
}
}
}
}

如何修改查询以添加子聚合,该子聚合将显示价格总和,即Ford为3000(两个文档的总和),Holden为2500(一个文档的总和)

最佳答案

以下查询将帮助您寻找所需的内容。

我只是为此添加了您的解决方案。我已经使用了Reverse Nested Aggregation,然后再次使用Sum Aggregation应用了Nested Aggregation post。

因此,您的查询层次结构如下:

Nested Aggregation
- Terms Aggregation
- Reverse Nested Aggregation to back to parent doc
- Nested Aggregation to enter into nested price document
- Sum Aggregation to calculate all the prices

汇总查询:
POST <your_index_name>/_search
{
"size":0,
"aggs":{
"metadata":{
"nested":{
"path":"metadata"
},
"aggs":{
"model_filter":{
"filter":{
"term":{
"metadata.key":"model"
}
},
"aggs":{
"model_counter":{
"terms":{
"field":"metadata.str_value",
"size":1000
},
"aggs":{
"reverseNestedAgg":{
"reverse_nested":{},
"aggs":{
"metadata":{
"nested":{
"path":"metadata"
},
"aggs":{
"sum":{
"sum":{
"field":"metadata.int_value"
}
}
}
}
}
}
}
}
}
}
}
}
}
}

请注意,我添加了 "size": 0以便仅返回聚合查询。您可以根据需要进行修改。

聚合解决方案:
{
"took" : 7,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 3,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
},
"aggregations" : {
"metadata" : {
"doc_count" : 6,
"model_filter" : {
"doc_count" : 3,
"model_counter" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "Ford",
"doc_count" : 2,
"reverseNestedAgg" : {
"doc_count" : 2,
"metadata" : {
"doc_count" : 4,
"sum" : {
"value" : 3000.0
}
}
}
},
{
"key" : "Holden",
"doc_count" : 1,
"reverseNestedAgg" : {
"doc_count" : 1,
"metadata" : {
"doc_count" : 2,
"sum" : {
"value" : 2500.0
}
}
}
}
]
}
}
}
}
}

请注意,我已经在ES版本7中测试了上述查询。

重要的提示:

如果您的文档以以下格式结尾,则以上查询将不起作用。
POST /cars/_doc/1
{
"metadata": [
{
"key": "model",
"str_value": "Ford"
},
{
"key": "price",
"int_value": 1000
},
{
"key": "something else",
"int_value": 1000
}
]
}
// There are three nested documents with two documents having int_value field

我看到您提到过,您希望避免映射爆炸,因此您的架构就是这样。但是,如果发生上述情况,在这种情况下,您可能需要退后一步,重新设计模型,或者让服务层处理此聚合情况。

希望这可以帮助!

关于elasticsearch - 在Elasticsearch中,如何执行嵌套子聚合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56411737/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com