Elasticsearch:Global aggregation

在搜索执行上下文中定义所有文档的单个存储桶。 此上下文由你要搜索的索引和文档类型定义,但不受搜索查询本身的影响。 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 来返回全局的统计数据,并返回我们特定查询范围里的统计数据。

实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值