Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to filter terms aggregation

Currently I have something like this

aggs: {
  categories: {
    terms: {
      field: 'category'
    }
  }
}

and this is giving me number of products in each category. But I have additional condition. I need to get number of products in each category which are not sold already, so I need to perform filter on terms somehow.

Is there some elegant way of doing this using aggregation framework, or I need to write filtered query?

Thank you

like image 432
user232343 Avatar asked Jun 16 '14 20:06

user232343


People also ask

What is filter aggregation?

Filter aggregationeditA single bucket aggregation that narrows the set of documents to those that match a query. The previous example calculates the average price of all sales as well as the average price of all T-shirt sales.

What is terms aggregation in Kibana?

What is Kibana Aggregation? Aggregation refers to the collection of documents or a set of documents obtained from a particular search query or filter. Aggregation forms the main concept to build the desired visualization in Kibana.

What is sub aggregation in Elasticsearch?

The sub-aggregations will be computed for the buckets which their parent aggregation generates. There is no hard limit on the level/depth of nested aggregations (one can nest an aggregation under a "parent" aggregation, which is itself a sub-aggregation of another higher-level aggregation).


2 Answers

You can merge between Terms Aggregation and Filter Aggregation, and this is how it should look: (tested)

    aggs: {
      categories: {            
        filter: {term: {sold: true}},
        aggs: {
          names: {
            terms: {field: 'category'}
          }
        }
      }
    }

You can add also more conditions to the filter, I hope this helps.

like image 183
Brary Avatar answered Oct 07 '22 15:10

Brary


Just to add to the other answer, you can also use a nested query. This is similar to what I had to do. I'm using Elasticsearch 5.2.

From the docs, here is the basic syntax:

"aggregations" : {
    "<aggregation_name>" : {
        "<aggregation_type>" : {
            <aggregation_body>
        }
        [,"aggregations" : { [<sub_aggregation>]+ } ]?
    }
    [,"<aggregation_name_2>" : { ... } ]*
}

This is how I implemented it:

GET <path> core_data/_search
{
  "aggs": {
    "NAME": {
      "nested": {
        "path": "ATTRIBUTES"
      },
      "aggs": {
        "NAME": {
          "filter": {
            "term": {
              "ATTRIBUTES.ATTR_TYPE": "EDUCATION_DEGREE"
            }
          },
          "aggs": {
            "NAME": {
              "terms": {
                "field": "ATTRIBUTES.DESCRIPTION",
                "size": 100
              }
            }
          }
        }
      }
    }
  }
}

This filtered the data down to one bucket, which is what I needed.

like image 44
James Drinkard Avatar answered Oct 07 '22 17:10

James Drinkard