Aggregation over nested documents


#1

Folks,

First all great shout out to Elastic community and team for designing and building clean product. Great job!

I am running a query to generate aggregations on nested documents. I have created the gist of all the curl calls (index creation, mapping and query. ) As you see in the mapping and my query, I am trying to generate aggregations on item name. In this case aggregations are generated over query results. That said I see aggregation of other nested documents as well in final result.

Gist link:

For e.g
The aggregation result is:
"aggregations": {
"resellers": {
"doc_count": 5,
"min_price": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "Polo Ralph Lauren Classic-Fit Mesh Polo",
"doc_count": 3
},
{
"key": "Tommy Hilfiger Classic-Fit Ivy Polo",
"doc_count": 2
}
]
}
}
}

However I was expecting the result to be only sub documents which matched the query "Tommy Hilfiger Classic-Fit Ivy Polo"

"aggregations": {
    "resellers": {
        "doc_count": 5,
        "min_price": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
                {
                    "key": "Tommy Hilfiger Classic-Fit Ivy Polo",
                    "doc_count": 2
                }
            ]
        }
    }
}

Appreciate any help or pointers.


Return matched nested object instead of root parent document
(Dan Tuffery) #2

You need to apply a filter aggregation:

{
    "query": {
        "nested": {
            "path": "item",
            "query": {
                "query_string": {
                    "fields": [
                        "item.name"
                    ],
                    "query": "\"Tommy Hilfiger Classic-Fit Ivy Polo\""
                }
            }
        }
    },
    "aggs": {
        "resellers_path": {
            "nested": {
                "path": "item"
            },
            "aggs": {
                "resellers_filter": {
                    "filter": {
                        "term": {
                            "item.name.raw": "Tommy Hilfiger Classic-Fit Ivy Polo"
                        }
                    },
                    "aggs": {
                        "rawItem": {
                            "terms": {
                                "field": "item.name.raw"
                            }
                        }
                    }
                }
            }
        }
    }
}

#3

Hi Dan,

Thanks for your reply. Will it work for "query_string" type of query as well ?
For e.g here my query includes 2 fields (name and price) and I would like to show aggregation based on those sub documents only ?
"query": "item.name:Tommy AND item.price:30"

So in this case the result of aggregation should be just 1 document


#4

complete query:

{
"query": {
"nested": {
"path": "item",
"query": {
"query_string": {
"query": "item.name:Tommy AND item.price:30"
}
}
}
},
"aggs": {
"resellers_path": {
"nested": {
"path": "item"
},
"aggs": {
"resellers_filter": {
"filter": {
"term": {
"item.name.raw": "Tommy Hilfiger Classic-Fit Ivy Polo"
}
},
"aggs": {
"rawItem": {
"terms": {
"field": "item.name.raw"
}
}
}
}
}
}
}
}


(Dan Tuffery) #5

Yes, query string will work too,

{
    "query": {
        "nested": {
            "path": "item",
            "query": {
                "query_string": {
                    "query": "item.name:Tommy AND item.price:30"
                }
            }
        }
    },
    "aggs": {
        "resellers_path": {
            "nested": {
                "path": "item"
            },
            "aggs": {
                "resellers_filter": {
                    "filter": {
                        "query": {
                            "query_string": {
                                "query": "item.name:Tommy AND item.price:30"
                            }
                        }
                    },
                    "aggs": {
                        "rawItem": {
                            "terms": {
                                "field": "item.name.raw"
                            }
                        }
                    }
                }
            }
        }
    }
}

#6

Super! Thanks Dan, that works for my use case.

Jaikit


(Jonathan Aaron) #7

This worked well for me! The documentation needs to specify how to display the data of a nested object easily. I had to piece together a lot of docs to get to this solution. Thanks Dan!


(system) #8