Elasticsearch(五)范围限定的聚合查询rest请求与java-api
作者:ydw
地点:武汉
email:hyl19900208@163.com
在之前的聚合查询中,我们都是针对全局进行数据进行操作的,接下来我们要通过Elasticsearch的查询,本篇主要讲解的是,根据我们的条件先对数据进行过滤,之后再进行相关的聚合操作.
ps:数据还是请用我们第一篇中的数据ElasticSearch超强聚合查询(一)
案例一:先查询出制作厂商是福特公司的汽车,然后在车子的颜色进行聚合查询
rest-api:
GET /cars/transactions/_search
{
"query" : {
"match" : {
"make" : "ford"
}
},
"aggs" : {
"colors" : {
"terms" : {
"field" : "color"
}
}
}
}
java-api
@Test
public void testWithFilter(){
SearchResponse response = transportClient.prepareSearch("cars")
.setTypes("transactions")
.setQuery(
//查找条件
QueryBuilders.matchQuery("make","ford")
)
//根据条件查找到的结果再进行聚合
.addAggregation(
AggregationBuilders
.terms("colors")
.field("color")
)
.get();
Aggregation colors = response.getAggregations().get("colors");
System.out.println(colors);
}
返回结果
{
...
"hits": {
"total": 2,
"max_score": 1.6931472,
"hits": [
//由于我们并没有设置返回的文档数量,所以查询的结果也一并返回
{
"_source": {
"price": 25000,
"color": "blue",
"make": "ford",
"sold": "2014-02-12"
}
},
{
"_source": {
"price": 30000,
"color": "green",
"make": "ford",
"sold": "2014-05-18"
}
}
]
},
"aggregations": {
"colors": {
"buckets": [
{
"key": "blue",
"doc_count": 1
},
{
"key": "green",
"doc_count": 1
}
]
}
}
}
案例二:使用过滤后的数据聚合,再与全局数据聚合,多个聚合之间的对比,在官方文档中定义这种查询为全局桶查询.
比方说我们想知道福特汽车与 所有 汽车平均售价的比较。我们可以用普通的聚合(查询范围内的)得到第一个信息,然后用 全局 桶获得第二个信息。
rest-api
GET /cars/transactions/_search
{
"size" : 0,
"query" : {
"match" : {
"make" : "ford"
}
},
"aggs" : {
"single_avg_price": {
"avg" : { "field" : "price" }
},
"all": {
"global" : {},
"aggs" : {
"avg_price": {
"avg" : { "field" : "price" }
}
}
}
}
}
java-api
@Test
public void compareQuery(){
SearchResponse response = transportClient.prepareSearch("cars")
.setTypes("transactions")
.setQuery(
//查找条件
QueryBuilders.matchQuery("make","ford")
)
.addAggregation(
AggregationBuilders.avg("single_avg_price")
.field("price")
)
.addAggregation(
//在添加一个全局数据的查询
AggregationBuilders.global("avg_price_name")
.subAggregation(
AggregationBuilders.avg("avg_price")
.field("price")
)
)
.get();
Aggregation avg_price_name = response.getAggregations().get("avg_price_name");
System.out.println(avg_price_name);
}
result
{
"took": 6,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.6931472,
"hits": [
{
"_index": "cars",
"_type": "transactions",
"_id": "AWIFx7jO5idSEZHc8G0Q",
"_score": 0.6931472,
"_source": {
"price": 30000,
"color": "green",
"make": "ford",
"sold": "2014-05-18"
}
}
]
},
"aggregations": {
//这个是全局的平均结果
"avg_price_name": {
"doc_count": 7,
"avg_price": {
"value": 26714.285714285714
}
},
//只针对福特的聚合结果
"single_avg_price": {
"value": 30000.0
}
}
}