加权平均聚合
编辑加权平均聚合编辑
一个 single-value
指标聚合,它计算从聚合的文档中提取的数值的加权平均值。这些值可以从文档中的特定数值字段中提取。
在计算普通平均值时,每个数据点都有相同的“权重”……它对最终值贡献相等。另一方面,加权平均值对每个数据点进行不同的加权。每个数据点对最终值的贡献量是从文档中提取的。
作为公式,加权平均值是 ∑(value * weight) / ∑(weight)
普通平均值可以被认为是加权平均值,其中每个值都有一个隐含的权重 1
。
表 51. weighted_avg
参数
参数名称 | 描述 | 必需 | 默认值 |
---|---|---|---|
|
提供值的字段或脚本的配置 |
必需 |
|
|
提供权重的字段或脚本的配置 |
必需 |
|
|
数值响应格式化程序 |
可选 |
The value
and weight
objects have per-field specific configuration
示例编辑
如果我们的文档有一个 "grade"
字段,它保存 0-100 的数值分数,还有一个 "weight"
字段,它保存任意数值权重,我们可以使用以下方法计算加权平均值
response = client.search( index: 'exams', body: { size: 0, aggregations: { weighted_grade: { weighted_avg: { value: { field: 'grade' }, weight: { field: 'weight' } } } } } ) puts response
POST /exams/_search { "size": 0, "aggs": { "weighted_grade": { "weighted_avg": { "value": { "field": "grade" }, "weight": { "field": "weight" } } } } }
这将产生类似于以下内容的响应
{ ... "aggregations": { "weighted_grade": { "value": 70.0 } } }
虽然允许每个字段有多个值,但只允许一个权重。如果聚合遇到具有多个权重的文档(例如,权重字段是多值字段),它将中止搜索。如果您遇到这种情况,您应该构建一个 运行时字段 将这些值组合成单个权重。
此单个权重将独立地应用于从 value
字段中提取的每个值。
此示例展示了如何将具有多个值的单个文档与单个权重进行平均
response = client.index( index: 'exams', refresh: true, body: { grade: [ 1, 2, 3 ], weight: 2 } ) puts response response = client.search( index: 'exams', body: { size: 0, aggregations: { weighted_grade: { weighted_avg: { value: { field: 'grade' }, weight: { field: 'weight' } } } } } ) puts response
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" } } } } }
这三个值 (1
、2
和 3
) 将被包含为独立的值,所有值都具有 2
的权重
{ ... "aggregations": { "weighted_grade": { "value": 2.0 } } }
聚合返回 2.0
作为结果,这与我们手动计算时所期望的结果一致:((1*2) + (2*2) + (3*2)) / (2+2+2) == 2
运行时字段编辑
如果您必须对与索引值不完全匹配的值进行求和或加权,请在 运行时字段 上运行聚合。
response = client.index( index: 'exams', refresh: true, body: { grade: 100, weight: [ 2, 3 ] } ) puts response response = client.index( index: 'exams', refresh: true, body: { grade: 80, weight: 3 } ) puts response response = client.search( index: 'exams', filter_path: 'aggregations', body: { size: 0, runtime_mappings: { 'weight.combined' => { type: 'double', script: "\n double s = 0;\n for (double w : doc['weight']) {\n s += w;\n }\n emit(s);\n " } }, aggregations: { weighted_grade: { weighted_avg: { value: { script: 'doc.grade.value + 1' }, weight: { field: 'weight.combined' } } } } } ) puts response
POST /exams/_doc?refresh { "grade": 100, "weight": [2, 3] } POST /exams/_doc?refresh { "grade": 80, "weight": 3 } POST /exams/_search?filter_path=aggregations { "size": 0, "runtime_mappings": { "weight.combined": { "type": "double", "script": """ double s = 0; for (double w : doc['weight']) { s += w; } emit(s); """ } }, "aggs": { "weighted_grade": { "weighted_avg": { "value": { "script": "doc.grade.value + 1" }, "weight": { "field": "weight.combined" } } } } }
这应该看起来像
{ "aggregations": { "weighted_grade": { "value": 93.5 } } }
缺失值编辑
默认情况下,聚合会排除 value
或 weight
字段的值缺失或为 null
的文档。使用 missing
参数来指定这些文档的默认值。
POST /exams/_search { "size": 0, "aggs": { "weighted_grade": { "weighted_avg": { "value": { "field": "grade", "missing": 2 }, "weight": { "field": "weight", "missing": 3 } } } } }