# Counting matching parent documents by aggregations on child documents

**URL:** <https://discuss.elastic.co/t/counting-matching-parent-documents-by-aggregations-on-child-documents/29055>\
**Category:** Elasticsearch\
**Created:** [September 10, 2015, 5:40pm UTC](https://discuss.elastic.co/t/counting-matching-parent-documents-by-aggregations-on-child-documents/29055 "2015-09-10T17:40:27Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![andrisp](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/andrisp/32/4705_2.png) [@andrisp](https://discuss.elastic.co/u/andrisp)\
**Post date:** [September 10, 2015, 5:40pm UTC](https://discuss.elastic.co/t/counting-matching-parent-documents-by-aggregations-on-child-documents/29055/1 "2015-09-10T17:40:27Z")

</div>

I have two document types:

1. ads (title, url and similar fields)
2. ad\_views (time, user\_id, gender, age, country and similar fields). ad\_views document type has ads as parent.

The wanted end result is search form where user can find ads by choosing ad\_views parameters. For example, find all ads who have been viewed by male, aged 18-25, living in UK. I also want to display "faceted search" form (like in [amazon.com](http://amazon.com) and many other sites) where you can see number of items (ads) under each filter/search option.

The searching (getting filtered list of docs) part is clear, but not the aggregations. I'm trying to figure out how to use aggregations on the child document properties, but instead of getting child document counts I would like to get counts for ads documents.

For example if I have data like this:

```
ad: "free beer in UK"
    ad view: male
ad: "free beer in Scotland"
    ad view: male
    ad view: male
    ad view: female
ad: "free beer in Wales"
    ad view: male
    ad view: male

```

And query like this:

```
GET /test/ads/_search
{
   "aggs": {
        "genders": {
            "children": {
                "type": "ad_views"
            },
            "aggs": {
                "gender": {
                    "terms": {
                        "field": "gender"
                    }
                }
            }
        }
    },
    "query" : {
        "term" : { 
            "title" : "free beer" 
        }
    }
}

```

The search will return me three ads. And in aggregations I will get male=5 and female=1 (that is - it will return total term counts in sub documents), but what I want is to get ads counts, that is, male=3, female=1 (there are three ads documents who have one or more male ad view, and one ads document who have one or more female ad view).

How can I achieve this?

---

<div class="post-metadata">

**Author:** ![andrisp](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/andrisp/32/4705_2.png) [@andrisp](https://discuss.elastic.co/u/andrisp)\
**Post date:** [September 11, 2015, 7:59am UTC](https://discuss.elastic.co/t/counting-matching-parent-documents-by-aggregations-on-child-documents/29055/2 "2015-09-11T07:59:51Z")

</div>

Please let me know if the description is unclear, I really need to find a solution for this 🙂

---

<div class="post-metadata">

**Author:** ![masaru](https://avatars.discourse-cdn.com/v4/letter/m/a9a28c/32.png) [@masaru](https://discuss.elastic.co/u/masaru)\
**Post date:** [September 14, 2015, 7:14am UTC](https://discuss.elastic.co/t/counting-matching-parent-documents-by-aggregations-on-child-documents/29055/3 "2015-09-14T07:14:18Z")

</div>

That would require parent aggregation, which is [yet to be implemented](https://github.com/elastic/elasticsearch/issues/5306) [1]

If the number of values in child documents is limited, you could use filter aggregation with `has_child` filter as a workaround. In your particular case, two filter aggregations, one for male another for female.

Masaru

[1] [https://github.com/elastic/elasticsearch/issues/5306](https://github.com/elastic/elasticsearch/issues/5306)

---

<div class="post-metadata">

**Author:** ![andrisp](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/andrisp/32/4705_2.png) [@andrisp](https://discuss.elastic.co/u/andrisp)\
**Post date:** [September 14, 2015, 1:03pm UTC](https://discuss.elastic.co/t/counting-matching-parent-documents-by-aggregations-on-child-documents/29055/4 "2015-09-14T13:03:40Z")

</div>

Thanks, Masaru, will try your proposed workaround on limited value fields.  
Any ideas on workaround on not-so-limited value fields? For example, if there would be a "city" field with potentially hundreds of values?

---

<div class="post-metadata">

**Author:** ![andrisp](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/andrisp/32/4705_2.png) [@andrisp](https://discuss.elastic.co/u/andrisp)\
**Post date:** [September 14, 2015, 2:12pm UTC](https://discuss.elastic.co/t/counting-matching-parent-documents-by-aggregations-on-child-documents/29055/5 "2015-09-14T14:12:52Z")

</div>

I'm looking into nested / reverse nested aggregations (I think it will not be a big problem for me to switch to nested docs instead of parents/childs), but not sure exactly if these aggregations will do what I want. Having a bit hard time to grasp the concepts.

---

<div class="post-metadata">

**Author:** ![andrisp](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/andrisp/32/4705_2.png) [@andrisp](https://discuss.elastic.co/u/andrisp)\
**Post date:** [September 17, 2015, 6:27am UTC](https://discuss.elastic.co/t/counting-matching-parent-documents-by-aggregations-on-child-documents/29055/6 "2015-09-17T06:27:40Z")

</div>

Moved ad\_views as nested documents instead of children.

Now I'm trying to count ads per gender, first by filtering on nested docs(title and date of birth fields).

Added reverse\_nested to get this doc count. The problem is that "gender\_count" aggregation on the nested documents "ad\_views.account.gender" returns me TOTAL number of the documents who has a ad\_views with this gender. It ignores date of birth in the nested documents.

See aggregation example below. Any ideas on how to do this?

```
"genders": {
    "filter": {                        
        "and": [
            {"term": {"title": "free beer"}},
            {
                "nested": {
                    "path": "ad_views",
                    "filter": {
                        "and": [
                            {"range": {"ad_views.dob": {"gte": "1980-09-15", "lt": "1990-09-15"}}}
                        ]
                    }
                }
            }
        ]
    },       
    "aggs": {
        "genders1": {
            "nested": {
                "path" : "ad_views"
            },
            "aggs": {
                "gender_count": {
                    "terms": {
                        "field": "ad_views.gender"
                    },
                    "aggs": {
                        "back_to_ads": {
                            "reverse_nested": {}
                        }
                    }
                }
            }
        }
    }
}
```

---

<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, 11:49pm UTC](https://discuss.elastic.co/t/counting-matching-parent-documents-by-aggregations-on-child-documents/29055/7 "2017-07-05T23:49:51Z")

</div>


