ElasticSearch:是否可以按分数加权 "Weighted Avg Aggregation"?

ElasticSearch: Is it possible to do a "Weighted Avg Aggregation" weighted by the score?

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

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

它应该给我我想要的。但是我收到了一个空值:

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

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

当您调试 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]
其中

None 包含有关您尝试访问的查询 _score 的信息,因为聚合在独立于查询级评分的上下文中运行。这意味着 weight 值需要

  • 存在于文档中或
  • 存在于文档中 + 是 modifiable
  • 是一个查询时间常量(如 420.1

解决方法是对检索到的 price 应用数学函数,例如

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

@jzzfs 我正在尝试使用 "avg of the first N results (ordered by _score)" 的方法,使用 top hits aggregation:

{
    "query": {
        "bool": {
            "should": [
                ...
            ],
            "minimum_should_match": 0
        }
    },
    "size": 0,
    "from": 0,
    "sort": [
        {
            "_score": {
                "order": "desc"
            }
        }
    ],
    "aggs": {
        "top_avg_price": {
            "avg": {
                "field": "price.max"
            }
        },
        "aggs": {
            "top_hits": {
                "size": 10, // N: Changing the number of results doesn't change the top_avg_price 
                "_source": {
                    "includes": [
                        "price.max"
                    ]
                }
            }
        }
    },
    "explain": "false"
}

正在对主要结果进行平均聚合,而不是 top_hits 聚合。 我想 top_avg_rpice 应该是 top_hits 的子聚合。但我认为那是不可能的ATM。