elasticsearch中最小模式的弹性堆栈统计聚合

vx6bjr1n  于 2021-06-10  发布在  ElasticSearch
关注(0)|答案(1)|浏览(347)

我在elasticsearch中有下面的Map

{
       "properties":{
          "Costs":{
             "type":"nested",
             "properties":{
                "price":{
                   "type":"integer"
                }
             }
          }
       }
    }

所以每个文档都有一个数组字段costs,其中包含许多元素,每个元素中都有price。我想找到最小和最大价格的条件是-从每个数组的元素与最低价格应考虑。所以它基本上是每个数组的最小值中的min/max。
假设我有两个文档,其中costs字段为

Costs: [
 {
  "price": 100,
 },
 {
  "price": 200,
 }
]

Costs: [
 {
  "price": 300,
 },
 {
  "price": 400,
 }
]

所以我需要找到统计数据这是我目前使用的查询

{
   "costs_stats":{
      "nested":{
         "path":"Costs"
      },
      "aggs":{
         "price_stats_new":{
            "stats":{
               "field":"Costs.price"
            }
         }
      }
   }
}

它给了我这个:

"min" : 100,
"max" : 400

但是我需要在考虑每个数组的最小元素之后找到统计信息。所以这就是我需要的:

"min" : 100,
"max" : 300

就像我们在sort中有一个“mode”选项一样,在stats聚合中是否也有类似的东西,或者任何其他实现这个的方法,可能是使用脚本或其他什么。请建议。我真的被困在这里了。
如果需要什么,请告诉我
更新1:
在最小值中查找最小值/最大值的查询

{
   "_source":false,
   "timeout":"5s",
   "from":0,
   "size":0,
   "aggs":{
      "price_1":{
         "terms":{
            "field":"id"
         },
         "aggs":{
            "price_2":{
               "nested":{
                  "path":"Costs"
               },
               "aggs":{
                  "filtered":{
                     "aggs":{
                        "price_3":{
                           "min":{
                              "field":"Costs.price"
                           }
                        }
                     },
                     "filter":{
                        "bool":{
                           "filter":{
                              "range":{
                                 "Costs.price":{
                                    "gte":100
                                 }
                              }
                           }
                        }
                     }
                  }
               }
            }
         }
      },
      "minValue":{
         "min_bucket":{
            "buckets_path":"price_1>price_2>filtered>price_3"
         }
      }
   }
}

只有少数桶来了,因此最小/最大桶来了,这是不正确的。有尺码限制吗。

4bbkushb

4bbkushb1#

实现用例的一种方法是再添加一个字段 id ,在每个文档中。在…的帮助下 id 可以执行字段项聚合,因此将动态构建bucket—每个惟一值一个bucket。
然后,我们可以应用最小聚合,它将返回从聚合文档中提取的数值中的最小值。
添加索引数据、Map、搜索查询和搜索结果的工作示例
索引Map:

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

索引数据:

{
  "id":1,
  "Costs": [
    {
      "price": 100
    },
    {
      "price": 200
    }
  ]
}
{
  "id":2,
  "Costs": [
    {
      "price": 300
    },
    {
      "price": 400
    }
  ]
}

搜索查询:

{
    "size": 0,
    "aggs": {
        "id_terms": {
            "terms": {
                "field": "id",
                "size": 15              <-- note this
            },
            "aggs": {
                "nested_entries": {
                    "nested": {
                        "path": "Costs"
                    },
                    "aggs": {
                        "min_position": {
                            "min": {
                                "field": "Costs.price"
                            }
                        }
                    }
                }
            }
        }
    }
}

搜索结果:

"aggregations": {
    "id_terms": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": 1,
          "doc_count": 1,
          "nested_entries": {
            "doc_count": 2,
            "min_position": {
              "value": 100.0
            }
          }
        },
        {
          "key": 2,
          "doc_count": 1,
          "nested_entries": {
            "doc_count": 2,
            "min_position": {
              "value": 300.0
            }
          }
        }
      ]
    }

也可以使用stats聚合来实现(如果您再添加一个字段 id 唯一标识文档的)

{
  "size": 0,
  "aggs": {
    "id_terms": {
      "terms": {
        "field": "id",
        "size": 15              <-- note this
      },
      "aggs": {
        "costs_stats": {
          "nested": {
            "path": "Costs"
          },
          "aggs": {
            "price_stats_new": {
              "stats": {
                "field": "Costs.price"
              }
            }
          }
        }
      }
    }
  }
}

更新1:
要在这些最小值中找到最大值(如上面的查询所示),可以使用max bucket聚合

{
  "size": 0,
  "aggs": {
    "id_terms": {
      "terms": {
        "field": "id",
        "size": 15         <-- note this
      },
      "aggs": {
        "nested_entries": {
          "nested": {
            "path": "Costs"
          },
          "aggs": {
            "min_position": {
              "min": {
                "field": "Costs.price"
              }
            }
          }
        }
      }
    },
    "maxValue": {
      "max_bucket": {
        "buckets_path": "id_terms>nested_entries>min_position"
      }
    }
  }
}

搜索结果:

"aggregations": {
    "id_terms": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": 1,
          "doc_count": 1,
          "nested_entries": {
            "doc_count": 2,
            "min_position": {
              "value": 100.0
            }
          }
        },
        {
          "key": 2,
          "doc_count": 1,
          "nested_entries": {
            "doc_count": 2,
            "min_position": {
              "value": 300.0
            }
          }
        }
      ]
    },
    "maxValue": {
      "value": 300.0,
      "keys": [
        "2"
      ]
    }
  }

相关问题