首页 > 解决方案 > ElasticSearch:是否可以按分数加权进行“加权平均聚合”?

问题描述

我正在尝试对价格字段 ( ) 执行平均price.avg。但我希望查询的最佳匹配对平均值的影响比最新的影响更大,因此平均值应由计算的分数字段加权。这是我正在实施的聚合。

{
    "query": {...},
    "size": 100,
    "aggs": {
        "weighted_avg_price": {
            "weighted_avg": {
                "value": {
                    "field": "price.avg"
                },
                "weight": {
                    "script": "_score"
                }
            }
        }
    }
}

它应该给我我想要的。但相反,我收到一个空值:

{...
    "hits": {...},
    "aggregations": {
        "weighted_avg_price": {
            "value": null
        }
    }
}

有什么我想念的吗?这个聚合查询可行吗?有什么解决方法吗?

标签: elasticsearchelasticsearch-aggregationelasticsearch-query

解决方案


当您调试内部可用的内容时script

GET prices/_search
{
  "size": 0,
  "aggs": {
    "weighted_avg_price": {
      "weighted_avg": {
        "value": {
          "field": "price"
        },
        "weight": {
          "script": "Debug.explain(new ArrayList(params.keySet()))"
        }
      }
    }
  }
}

以下内容被吐出

[doc, _source, _doc, _fields]

这些都不包含有关_score您尝试访问的查询的信息,因为聚合在与查询级别评分不同的上下文中运行。这意味着该weight值需要

  • 存在于文档中或
  • 存在于文档中 + 可修改
  • 是查询时间常数(如42or 0.1

一种解决方法可能是将数学函数应用于检索到的,price例如

"script": "Math.pow(doc.price.value, 0.5)"


推荐阅读