ElasticSearch---es之Post Filter,聚合后过滤
使用场景
平常我们使用es,都会先查询、过滤后再进行聚合,但有时也需要在聚合后再过滤,
这时可以使用"后置过滤器",也就是PostFilter。
实践理解
阅读了官方文档后,感觉学习还是要多动手,才会理解更透彻。
参考官方文档,列举了以下例子。可以跟着动手玩一下。
- 新建索引:
PUT /shirts
{
"mappings": {
"item": {
"properties": {
"brand": { "type": "keyword"},
"color": { "type": "keyword"}
}
}
}
}
- 新增数据:
第一条数据:
PUT /shirts/item/1?refresh
{
"brand": "gucci",
"color": "blue"
}
第二条数据:
PUT /shirts/item/2?refresh
{
"brand": "gucci",
"color": "red"
}
第三条数据:
PUT /shirts/item/3?refresh
{
"brand": "dior",
"color": "red"
}
- PostFilter,聚合后过滤:
GET /shirts/_search
{
"query": {
"bool": {
"filter": [
{ "term": { "brand": "gucci" }}
]
}
},
"size": 20,
"aggs": {
"agg_color": {
"terms": { "field": "color" }
}
},
"post_filter": {
"term": { "color": "red" }
}
}
在以上的DSL上,
(1)用filter过滤出gucci品牌的衬衫;
(2)用aggs对color进行聚合;
(3)用post_filter过滤出color为红色的衬衫;
- 查询结果 :
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0,
"hits": [
{
"_index": "shirts",
"_type": "item",
"_id": "2",
"_score": 0,
"_source": {
"brand": "gucci",
"color": "red"
}
}
]
},
"aggregations": {
"agg_color": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "blue",
"doc_count": 1
},
{
"key": "red",
"doc_count": 1
}
]
}
}
}
用filter过滤出gucci品牌的衬衫,用aggs对color进行聚合。
我们看一下"aggregations"的结果,可以看到color聚合结果中,是存在blue的,
而且"key"为red的doc_count只有一条,而不是两条,品牌为dior的red衬衫已经去掉了。
用post_filter过滤出color为红色的衬衫,所以"hits"的结果是没有blue的。
说明是先filter,再agg,最后再postFilter的。
参考资料
http://doc.codingdict.com/elasticsearch/105/
https://www.elastic.co/guide/en/elasticsearch/guide/current/_post_filter.html