Teimuraz
Teimuraz

Reputation: 9325

ElasticSearch: How to filter aggregation by keys count?

I have following es query:

{
  "size": 0,
   "aggs" : {
        "make": {
            "terms" : { "field" : "make", size: 0 },           
            "aggs": {
              "model": {
                "terms": {
                  "field": "model"
                }
              }
            }
        }
      }    
}

Which gives me following (schematic) result.

---------------------
key: Mercedes

doc_count:201

    key: S350
    doc_count: 100

    key: E200
    doc_count: 101

---------------------
key: Bmw    

doc_count: 500
    key: 750
    doc_count: 300

    key: 530
    doc_count: 200

---------------------
key: SuperCar

doc_count: 300

    key: T123
    doc_count: 300

But I need to get only aggregations for Mercedes and Bmw. SuperCar key should be ingored and not shown at all.

E.g, I need to filter aggregations by sub aggregations unique keys count.

Is it possible?

Upvotes: 1

Views: 1446

Answers (2)

maximus
maximus

Reputation: 1548

I add an answer here in case someone have the same use case. From the question, my guess is that the author want to filter aggregation results base on their key counts, e.g.: search for all car brands that have at least 2 models.

Thanks @lpeixotoo for pointing out the cardinality aggregation, the next step is to use a bucket selector aggregation, I update the query as below:

{
  "size": 0,
  "aggs" : {
    "make": {
      "terms" : { "field" : "make", size: 0 },           
      "aggs": {
        "model": {
          "terms": {
            "field": "model"
          }
        },
        "model_count": {
           "cardinality": {
              "field":"model"
          }
        },
        "model_count_filter": {
          "bucket_selector": {
            "buckets_path": {
              "modelCount": "model_count"
            },
            "script": "params.modelCount >= 2"
          }
        }
      }
    }
  }    
}

Upvotes: 0

lpeixotoo
lpeixotoo

Reputation: 68

Teimuraz,

But I need to get only aggregations for Mercedes and Bmw. SuperCar key should be ingored and not shown at all.

You can use a must_not bool query or a must one depending on your perspective, for more informations:

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html

E.g, I need to filter aggregations by sub aggregations unique keys count.

Is it possible?

If i got you right, you want to know how many model are there for each make, right? For that you can use the cardinality aggregation:

{
  "size": 0,
   "aggs" : {
        "make": {
            "terms" : { "field" : "make", size: 0 },           
            "aggs": {
              "model": {
                "terms": {
                  "field": "model"
                }
              },
              "model_count":{
                 "cardinality":{
                    "field":"model"
                 }
              }
            }
        }
      }    
}

Upvotes: 1

Related Questions