当前位置: 代码迷 >> 综合 >> Elasticsearch:Global aggregation
  详细解决方案

Elasticsearch:Global aggregation

热度:67   发布时间:2024-01-28 21:01:58.0

在搜索执行上下文中定义所有文档的单个存储桶。 此上下文由你要搜索的索引和文档类型定义,但不受搜索查询本身的影响。 Global aggregators 只能作为顶级聚合器放置,因为将 global aggregator 嵌入另一个存储桶聚合器中没有意义。

我们还是先用一个具体的例子来展示。

 

准备数据

我们先在 Kibana 中使用 _bulk 创建如下的一个索引:

POST _bulk
{ "index" : { "_index" : "users", "_id": 1} }
{"user":"bill", "age": 30, "country": "FR", "category": "A"}
{ "index" : { "_index" : "users", "_id": 2} }
{"user":"Marie", "age": 32, "country": "US", "category": "A"}
{ "index" : { "_index" : "users", "_id": 3} }
{"user":"Clarie", "age": 32, "country": "US", "category": "A"}
{ "index" : { "_index" : "users", "_id": 4} }
{"user":"Tom", "age": 44, "country": "DE", "category": "B"}
{ "index" : { "_index" : "users", "_id": 5} }
{"user":"John", "age": 40, "country": "US", "category": "B"}
{ "index" : { "_index" : "users", "_id": 6} }
{"user":"Emma", "age": 26, "country": "US", "category": "B"}

全局聚合

接下来,我们使用 global aggregation 来进行查询:

POST users/_search?size=0
{"query": {"match": {"category": "A"}},  "aggs": {"all_users": {"global": {},"aggs": {"avg_age": {"avg": {"field": "age"}}}},"a_category": {"avg": {"field": "age"}  }}
}

在上面,我们可以看到 "global": {}, 它含有一个空的主体。紧挨着它的是它的一个 sub-aggregation 用来计算所有文档的平均年龄而不受制于在它前面的那个 query 的影响。上面查询的返回结果是:

{"took" : 1,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 3,"relation" : "eq"},"max_score" : null,"hits" : [ ]},"aggregations" : {"a_category" : {"value" : 31.333333333333332},"all_users" : {"doc_count" : 6,"avg_age" : {"value" : 34.0}}}
}

上面的结果显示所有用户的平均年龄为34.0。其实就是 (30+32+32+44+40+26)/6 = 34。显然这个结果是不受任何的如下的 query 的影响的:

"query": {"match": {"category": "A"}},  

紧接着 global aggregation 的是一个针对所有的属于 A category 的一个统计。它的平均值是 31.33333333。其实就是 (30+32+32)/3 = 31.33333。这个统计的结果显然是受 query 的结果而影响的。

 

我们也可以做类似如下的查询:

POST users/_search?size=0
{"query": {"match": {"category": "A"}},"aggs": {"all_users": {"global": {},"aggs": {"avg_age": {"avg": {"field": "age"}}}},"fromUS": {"filter": {"match": {"country": "US"}}}}
}

返回的结果是:

{"took" : 1,"timed_out" : false,"_shards" : {"total" : 1,"successful" : 1,"skipped" : 0,"failed" : 0},"hits" : {"total" : {"value" : 3,"relation" : "eq"},"max_score" : null,"hits" : [ ]},"aggregations" : {"fromUS" : {"doc_count" : 2},"all_users" : {"doc_count" : 6,"avg_age" : {"value" : 34.0}}}
}

在实际的使用中,我们可以使用 global aggregation 来返回全局的统计数据,并返回我们特定查询范围里的统计数据。

  相关解决方案