Home > Net >  Show aggregations of same category after filter
Show aggregations of same category after filter

Time:11-04

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

  1. 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
        }
      ]
    }
  }
  1. Post_filter

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
        }
      ]
    }
  }
  • Related