1
votes

I have a hierarchy of document types two levels deep. The documents are related by parent-child relationships as follows: category > sub_category > item i.e. each sub_category has a _parent field referring to a category id, and each item has a _parent field referring to a sub_category id.

Each item has a price field. Given a query for categories, which includes conditions for sub-categories and items, I want to calculate a total price for each sub_category.

My query looks something like this:

{
    "query": {
        "has_child": {
            "child_type": "sub_category",
            "query": {
                "has_child": {
                    "child_type": "item",
                    "query": {
                        "range": {
                            "price": {
                                "gte": 100,
                                "lte": 150
                            }
                        }
                    }
                }
            }
        }
    }
}

My aggregation to calculate the price for each sub-category looks like this:

{
    "aggs": {
        "categories": {
            "terms": {
                "field": "id"
            },
            "aggs": {
                "sub_categories": {
                    "children": {
                        "type": "sub_category"
                    },
                    "aggs": {
                        "sub_category_ids": {
                            "terms": {
                                "field": "id"
                            },
                            "aggs": {
                                "items": {
                                    "children": {
                                        "type": "item"
                                    },
                                    "aggs": {
                                        "price": {
                                            "sum": {
                                                "field": "price"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

Despite the query response listing matching results, the aggregation response doesn't match any items:

{
    "aggregations": {
        "categories": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 0,
            "buckets": [
                {
                    "key": "category1",
                    "doc_count": 1,
                    "sub_categories": {
                        "doc_count": 3,
                        "sub_category_ids": {
                            "doc_count_error_upper_bound": 0,
                            "sum_other_doc_count": 0,
                            "buckets": [
                                {
                                    "key": "subcat1",
                                    "doc_count": 1,
                                    "items": {
                                        "doc_count": 0,
                                        "price": {
                                            "value": 0
                                        }
                                    }
                                },
                                {
                                    "key": "subcat2",
                                    "doc_count": 1,
                                    "items": {
                                        "doc_count": 0,
                                        "price": {
                                            "value": 0
                                        }
                                    }
                                },
                                {
                                    "key": "subcat3",
                                    "doc_count": 1,
                                    "items": {
                                        "doc_count": 0,
                                        "price": {
                                            "value": 0
                                        }
                                    }
                                }
                            ]
                        }
                    }
                }]
            }
        }
    }

However, omitting the sub_category_ids aggregation does cause the items to appear and for prices to be summed at the level of the categories aggregation. I would expect including the sub_category_ids aggregation to simply change the level at which the prices are summed.

Am I misunderstanding how the aggregation is evaluated, and if so how could I modify it to display the summed prices for each sub-category?

1
For the benefit of others, @ChintanShah25 created this related issue in the ES repo.Val
I opened an issue as @Val said, If it is an urgent issue you might want to downgrade to 1.7 as your query is working with ES 1.7, I am facing similar issue in my project, This question also highlights the same problemChintanShah25
Thanks for the replies! Good to know that a bug might be the cause. I'll keep an eye on the issue.tmw
The following PR will solve the issue and be available in ES 2.1.2.Val
Either of you, if you'd like, feel free to post the issue/PR as an answer to my question.tmw

1 Answers

1
votes

I opened an issue #15413, regarding children aggregation as I and other folks were facing similar issues in ES 2.0

Apparently the problem according to ES developer @martijnvg was that

The children agg makes an assumption (that all segments are being seen by children agg) that was true in 1.x but not in 2.x

PR #15457 fixed this issue, again from @martijnvg

Before we only evaluated segments that yielded matches in parent aggs, which caused us to miss to evaluate child docs in segments we didn't have parent matches for.

The fix for this is stop remember in what segments we have matches for and simply evaluate all segments. This makes the code simpler and we can still quickly see if a segment doesn't hold child docs like we did before

This pull request has been merged and it has also been back ported to the 2.x, 2.1 and 2.0 branches.