加权平均(weighted_avg)聚合

single-value(单值)度量聚合,计算从聚合文档中提取的数值的加权平均值。 这些值可以从文档中指定的 numeric 字段中提取。

计算常规平均值时,每个数据点都有相同的“权重(weight)”…它对最终的值的贡献是相同的。 加权平均值就不同了,它会对每个数据点进行不同的加权。 每个数据点对最终的值的贡献量是从文档中提取的,或者由脚本提供。

加权平均值公式是 ∑(value * weight) / ∑(weight)

常规平均值也可视为加权平均值,只是每个值的隐含权重为1

表 3. weighted_avg 参数

参数名称 描述 要求 默认值

value

提供值的字段或脚本的配置

必需

   

weight

提供权重的字段或脚本的配置

必需

format

数值响应格式化程序

可选

value_type

关于纯脚本或未映射字段的值的提示

可选

valueweight 对象每个字段可有特定的配置:

表 4. value 参数

参数名称 描述 要求 默认值

field

要从其中提取值的字段

必需

missing

字段完全缺失时使用的值

可选

表 5. weight 参数

参数名称 描述 要求 默认值

field

要从其中提取权重的字段

必需

missing

字段完全缺失时使用的权重值

可选

例子

如果我们的文档有一个保存 0-100 数值分数的 "grade" 字段和一个保存任意数值权重的 "weight" 字段,我们可以使用以下公式计算加权平均值:

POST /exams/_search
{
    "size": 0,
    "aggs" : {
        "weighted_grade": {
            "weighted_avg": {
                "value": {
                    "field": "grade"
                },
                "weight": {
                    "field": "weight"
                }
            }
        }
    }
}

这将产生如下响应:

{
    ...
    "aggregations": {
        "weighted_grade": {
            "value": 70.0
        }
    }
}

虽然每个字段允许多个值((multiple values-per-field),但只允许一个权重。 如果聚合遇到具有多个权重的文档(例如,权重字段是多值字段(multi-value field)),将抛出异常。 如果遇到这种情况,需要为权重字段指定一个 script ,并使用该脚本将多个值组合成一个要使用的值。

这个权重将独立应用于从 value 字段中提取的每个值。

下面这个示例显示了如何使用单一权重对具有多个值的单个文档进行平均:

POST /exams/_doc?refresh
{
    "grade": [1, 2, 3],
    "weight": 2
}

POST /exams/_search
{
    "size": 0,
    "aggs" : {
        "weighted_grade": {
            "weighted_avg": {
                "value": {
                    "field": "grade"
                },
                "weight": {
                    "field": "weight"
                }
            }
        }
    }
}

grade的三个值(123)将作为独立的值包含在内,所有值的权重为2:

{
    ...
    "aggregations": {
        "weighted_grade": {
            "value": 2.0
        }
    }
}

聚合返回的结果是 2.0,这与我们手动计算时的预期相符: ((1*2) + (2*2) + (3*2)) / (2+2+2) == 2

脚本(script)

valueweight都可以从脚本中导出,而不是从字段中。 举个简单的例子,下面将使用脚本在文档中给gradeweight加 1:

POST /exams/_search
{
    "size": 0,
    "aggs" : {
        "weighted_grade": {
            "weighted_avg": {
                "value": {
                    "script": "doc.grade.value + 1"
                },
                "weight": {
                    "script": "doc.weight.value + 1"
                }
            }
        }
    }
}

缺失的值(missing values)

参数 missing 定义应该如何处理有缺失值的文档。 valueweight的默认行为不同:

默认情况下,如果 value 字段缺失,则忽略该文档,并继续聚合下一个文档。 如果 weight 字段缺失,则假设权重为 1 (类似于常规平均值)。

这两个默认值都可以用参数 missing 覆盖:

POST /exams/_search
{
    "size": 0,
    "aggs" : {
        "weighted_grade": {
            "weighted_avg": {
                "value": {
                    "field": "grade",
                    "missing": 2
                },
                "weight": {
                    "field": "weight",
                    "missing": 3
                }
            }
        }
    }
}