ElasticSearch 中使用最小模式的统计聚合

Stats Aggregation with Min Mode in ElasticSearch

我在 ElasticSearch 中有以下映射

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

所以每个文档都有一个数组字段Costs,里面有很多元素,每个元素里面都有价格。我想找到最低和最高价格,条件是 - 从每个数组中应该考虑最低价格的元素。所以基本上是min/max在每个数组的最小值中。

假设我有 2 个文档,成本字段为

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

就像我们在排序中有一个“模式”选项一样,在统计聚合中是否也有类似的东西,或者任何其他实现此目的的方法,可能使用脚本或其他东西。请建议。我真的卡在这里了。

如果有任何需要,请告诉我

更新 1:

在最小值中查找 min/max 的查询

{
   "_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"
         }
      }
   }
}

只有很少的桶来了,因此 min/max 就在其中,这是不正确的。有没有尺寸限制。

实现您的用例的一种方法是在每个文档中再添加一个字段id。在 id 字段的帮助下,可以执行 terms aggregation,因此将动态构建存储桶 - 每个唯一值一个存储桶。

然后,我们可以应用 min aggregation,这将 return 从聚合文档中提取的数值中的最小值。

添加包含索引数据、映射、搜索查询和搜索结果的工作示例

索引映射:

{
  "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
            }
          }
        }
      ]
    }

也可以使用统计聚合来实现(如果您再添加一个唯一标识您的文档的字段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 aggregation

{
  "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"
      ]
    }
  }