Hamid Mohayeji
Hamid Mohayeji

Reputation: 4285

Elasticsearch: Aggregation on filtered nested objects to find unique values

I have an array of objects (tags) in each document in Elasticsearch 5:

{
    "tags": [
        { "key": "tag1", "value": "val1" },
        { "key": "tag2", "value": "val2" },
        ...
    ]
}

Now I want to find unique tag values for a certain tag key. Something similiar to this SQL query:

SELECT DISTINCT(tags.value) FROM tags WHERE tags.key='some-key'

I have came to this DSL so far:

{
    "size": 0,
    "aggs": {
        "my_tags": {
            "nested": {
                "path": "tags"
            },
            "aggs": {
                "filter" : { "terms": { "tags.key": "tag1" } },
                "aggs": {
                    "my_tags_values": {
                        "terms" : {
                            "field" : "tags.value",
                            "size": 9999
                         }
                    }                   
                }
            }
        }
    }
}

But It is showing me this error:

[terms] unknown field [tags.key], parser not found.

Is this the right approach to solve the problem? Thanks for your help.

Note: I have declared the tags field as a nested field in my mapping.

Upvotes: 0

Views: 1948

Answers (2)

Eli
Eli

Reputation: 4936

Try Bool Query inside the Filter-Aggregation:

{
  "size": 0,
  "aggs": {
    "my_tags": {
      "nested": {
        "path": "tags"
      },
      "aggs": {
        "filter": {
          "bool": {
            "must": [
              {
                "term": {
                  "tags.key": "tag1"
                }
              }
            ]
          },
          "aggs": {
            "my_tags_values": {
              "terms": {
                "field": "tags.value",
                "size": 0
              }
            }
          }
        }
      }
    }
  }
}

BTW: if you want to retrieve all buckets, you can write 0 instead of 9999 in aggregation size.

Upvotes: 0

Andrei Stefan
Andrei Stefan

Reputation: 52368

You mixed up things there. You wanted probably to add a filter aggregation, but you didn't give it any name:

{
  "size": 0,
  "aggs": {
    "my_tags": {
      "nested": {
        "path": "tags"
      },
      "aggs": {
        "my_filter": {
          "filter": {
            "terms": {
              "tags.key": [
                "tag1"
              ]
            }
          },
          "aggs": {
            "my_tags_values": {
              "terms": {
                "field": "tags.value",
                "size": 9999
              }
            }
          }
        }
      }
    }
  }
}

Upvotes: 3

Related Questions