I would like to create filter and aggregations after filter for procuts in Elasticsearch. I am having base aggregations for all products:
"size": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 87,
"buckets": [
{
"key": "6",
"doc_count": 89
},
{
"key": "5,5",
"doc_count": 60
}
]
}
},
"brand": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 87,
"buckets": [
{
"key": "Apple",
"doc_count": 89
},
{
"key": "Samsung",
"doc_count": 60
},
{
"key": "Xiaomi",
"doc_count": 48
},
{
"key": "Huawei",
"doc_count": 33
}
]
}
}
After I make query for one of those brands and size like:
query": {
"bool": {
"filter": [
"term": {
"brand": "Samsung"
},
"term": {
"size": "6"
}
]
}
}
I am getting back aggregations only for selected brand. But i still want to see in aggregations all others brands with same size.
Is this possible with ES?
Thank you so much for all answers.
CodePudding user response:
I'm not sure I understand what you are looking for.
You could try this query (terms aggregation on brand and then sub-aggregations of size):
{
"size": 0,
"query": {
"match_all": {}
},
"aggs": {
"byBrand": {
"terms": {
"field": "brand"
},
"aggs": {
"bySize": {
"terms": {
"field": "size"
}
}
}
}
}
}
Otherwise, you could filter by size first and then aggregate by brand:
{
"query": {
"bool": {
"filter": {
"term": {
"size": "6"
}
}
}
},
"size": 0,
"aggs": {
"byBrand": {
"terms": {
"field": "brand"
}
}
}
}
If this does not help you, please add your expected output to the question.
CodePudding user response:
There are multiple ways to do it
- Using global and filter aggregation
Global aggregation - looks for all documents even those filtered by query.
Query
{
"query": {
"bool": {
"filter": [
{
"term": {
"brand.keyword": "Samsung"
}
},
{
"term": {
"size": "6"
}
}
]
}
},
"aggs": {
"all_brands": {
"global": {}, --> refer all documents
"aggs": {
"size_filter": { --> filter size 6
"filter": {
"term": {
"size": 6
}
},
"aggs": {
"all_brands_terms": {
"terms": {
"field": "brand.keyword",
"size": 10
}
}
}
}
}
}
}
}
Result
hits" : [
{
"_index" : "index67",
"_type" : "_doc",
"_id" : "FyERPYQBJutE-yZcbYF4",
"_score" : 0.0,
"_source" : {
"brand" : "Samsung",
"size" : 6
}
}
]
},
"aggregations" : {
"all_documents" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "Apple",
"doc_count" : 1
},
{
"key" : "Samsung",
"doc_count" : 1
}
]
}
}
When you use the post_filter parameter to filter search results, the search hits are filtered after the aggregations are calculated. A post filter has no impact on the aggregation results.
Query
{
"query": {
"bool": {
"filter": [
{
"term": {
"size": "6"
}
}
]
}
},
"aggs": {
"all_documents": {
"terms": {
"field": "brand.keyword",
"size": 10
}
}
},
"post_filter": {
"term": {
"brand.keyword": "Samsung"
}
}
}
Result
hits" : [
{
"_index" : "index67",
"_type" : "_doc",
"_id" : "FyERPYQBJutE-yZcbYF4",
"_score" : 0.0,
"_source" : {
"brand" : "Samsung",
"size" : 6
}
}
]
},
"aggregations" : {
"all_documents" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "Apple",
"doc_count" : 1
},
{
"key" : "Samsung",
"doc_count" : 1
}
]
}
}