使用場景
平常我們使用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