# How to aggregate nested key/value pairs ONLY IF they match a filter?

**URL:** <https://discuss.elastic.co/t/how-to-aggregate-nested-key-value-pairs-only-if-they-match-a-filter/53076>\
**Category:** Elasticsearch\
**Created:** [June 17, 2016, 1:41am UTC](https://discuss.elastic.co/t/how-to-aggregate-nested-key-value-pairs-only-if-they-match-a-filter/53076 "2016-06-17T01:41:39Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Drew\_Kutcharian](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/drew_kutcharian/32/742_2.png) [@Drew\_Kutcharian](https://discuss.elastic.co/u/Drew_Kutcharian)\
**Post date:** [June 17, 2016, 1:41am UTC](https://discuss.elastic.co/t/how-to-aggregate-nested-key-value-pairs-only-if-they-match-a-filter/53076/1 "2016-06-17T01:41:39Z")

</div>

Hi All,

I have a model similar to the following, where a user can have a set of `attributes` which are just key/value pairs. `attributes` are mapped as a `nested` field.

How can I get a list of all available countries? (Basically, all available values where `key = "country"`). I wasn't able to get the `filter` aggregation to work. It seems that `filter` aggregation operates on the `parent` doc.

```auto
{
  "id": 1234,
  "name": "John",
  "attributes": [
    {
      "key": "age",
      "value": 30
    },
    {
      "key": "address",
      "value": "123 Evergreen st"
    },
    {
      "key": "city",
      "value": "Los Angeles"
    },
    {
      "key": "country",
      "value": "USA"
    },
    {
      "key": "phone",
      "value": "310-234-2233"
    },
   ...
  ]
}

```

Thanks,

Drew

---

<div class="post-metadata">

**Author:** ![Glen\_Smith](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/glen_smith/32/111656_2.png) [@Glen\_Smith](https://discuss.elastic.co/u/Glen_Smith)\
**Post date:** [June 17, 2016, 2:20am UTC](https://discuss.elastic.co/t/how-to-aggregate-nested-key-value-pairs-only-if-they-match-a-filter/53076/2 "2016-06-17T02:20:22Z")

</div>

Perform a nested query on attributes.key: country, and do a nested terms agg on attributes.value.

---

<div class="post-metadata">

**Author:** ![Drew\_Kutcharian](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/drew_kutcharian/32/742_2.png) [@Drew\_Kutcharian](https://discuss.elastic.co/u/Drew_Kutcharian)\
**Post date:** [June 17, 2016, 3:29am UTC](https://discuss.elastic.co/t/how-to-aggregate-nested-key-value-pairs-only-if-they-match-a-filter/53076/3 "2016-06-17T03:29:30Z")

</div>

Wouldn't that return all the values for ALL the attributes for users who have the `key: country`? I want to get only the countries.

- Drew

---

<div class="post-metadata">

**Author:** ![Glen\_Smith](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/glen_smith/32/111656_2.png) [@Glen\_Smith](https://discuss.elastic.co/u/Glen_Smith)\
**Post date:** [June 17, 2016, 5:18am UTC](https://discuss.elastic.co/t/how-to-aggregate-nested-key-value-pairs-only-if-they-match-a-filter/53076/4 "2016-06-17T05:18:14Z")

</div>

Oh, right.

Yeah, not sure how to pull that off, except to have ordinary field/value pairs, or to have attributes as a child type.

Without diving into the other pros and cons of using parent/child, if they were parent/child, you would have a query something like:

```auto
POST people_props/attribute/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "has_parent": {
            "parent_type": "person",
            "query": {
              "term": {
                "name": "John"
              }
            }
          }
        },
        {
          "has_parent": {
            "parent_type": "person",
            "query": {
              "term": {
                "id": "1234"
              }
            }
          }
        },
        {
          "term": {
            "key": "country"
          }
        }
      ]
    }
  },
  "aggs": {
    "countries": {
      "terms": {
        "field": "value"
      }
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![Drew\_Kutcharian](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/drew_kutcharian/32/742_2.png) [@Drew\_Kutcharian](https://discuss.elastic.co/u/Drew_Kutcharian)\
**Post date:** [June 17, 2016, 6:04am UTC](https://discuss.elastic.co/t/how-to-aggregate-nested-key-value-pairs-only-if-they-match-a-filter/53076/5 "2016-06-17T06:04:27Z")

</div>

Unfortunately I can't use parent/child for this.

---

<div class="post-metadata">

**Author:** ![Glen\_Smith](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/glen_smith/32/111656_2.png) [@Glen\_Smith](https://discuss.elastic.co/u/Glen_Smith)\
**Post date:** [June 17, 2016, 6:35am UTC](https://discuss.elastic.co/t/how-to-aggregate-nested-key-value-pairs-only-if-they-match-a-filter/53076/6 "2016-06-17T06:35:01Z")

</div>

I guess you're stuck with reverting your key values to actual properties then. Or doing some client-side processing.

---

<div class="post-metadata">

**Author:** ![Drew\_Kutcharian](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/drew_kutcharian/32/742_2.png) [@Drew\_Kutcharian](https://discuss.elastic.co/u/Drew_Kutcharian)\
**Post date:** [June 18, 2016, 12:27am UTC](https://discuss.elastic.co/t/how-to-aggregate-nested-key-value-pairs-only-if-they-match-a-filter/53076/7 "2016-06-18T00:27:49Z")

</div>

No fortunately I figured it out.

For anyone stumbling on this problem in future, you can use the following aggregation:

```auto
{
  "size": 0,
  "aggs": {
    "attributes": {
      "nested": {
        "path": "attributes"
      },
      "aggs": {
        "key": {
          "filter": {
            "term": {
              "attributes.key": "country"
            }
          },
          "aggs": {
            "values": {
              "terms": {
                "field": "attributes.value"
              }
            }
          }
        }
      }
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![Glen\_Smith](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/glen_smith/32/111656_2.png) [@Glen\_Smith](https://discuss.elastic.co/u/Glen_Smith)\
**Post date:** [June 18, 2016, 3:16am UTC](https://discuss.elastic.co/t/how-to-aggregate-nested-key-value-pairs-only-if-they-match-a-filter/53076/8 "2016-06-18T03:16:51Z")

</div>

Nice!

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [July 5, 2017, 10:42pm UTC](https://discuss.elastic.co/t/how-to-aggregate-nested-key-value-pairs-only-if-they-match-a-filter/53076/9 "2017-07-05T22:42:35Z")

</div>


