为什么弹性搜索项bucket大小会影响内部反向聚合的doc_count



我一直在尝试从反向嵌套聚合中查找丢失的文档计数。

我的查询

"aggs": {
"mainGrouping": {
"nested": {
"path": "parent.child"
},
"aggs": {
"uniqueCount": {
"cardinality": {
"field": "parent.child.id"
}
},
"groupBy": {
"terms": {
"field": "parent.child.id",
"size": 20,  <- If I change this, my doc count for noOfParents changes
"order": [
{
"noOfParents": "desc"
}
]
},
"aggs": {
"noOfParents": {
"reverse_nested": {}
}
}
}
}
}

所以我在size:20上运行它。我有一个水桶,当我知道应该有9场比赛时,没有7个孩子的父母回来。我意外地注意到,如果我将术语聚合的大小更改为50,noOfParents正确地显示了这个桶的9。

为什么术语聚合的大小会影响反向聚合的doc_count?这是预期行为还是错误?我正在使用弹性搜索5.6。

您观察到的很可能是terms聚合的正常行为,因为文档计数是近似的。这既与reverse_nested无关,也与nested聚合无关。

简言之,由于数据分布在碎片上,Elasticsearch首先在每个碎片的本地进行最佳猜测,然后在碎片上组合结果。要获得更好、更详细的解释,请查看文档的这一部分。

为了确保实际情况确实如此,您可以添加启用explaintop_hits聚合:

"aggs": {
"noOfParents": {
"reverse_nested": {},
"aggs": {
"top hits": {
"top_hits": {
"size": 10,
"explain": true
}
}
}
}
}

这将为您提供匹配的父文档及其碎片ID的列表。类似这样的东西:

"aggregations": {
"mainGrouping": {
...
"groupBy": {
...
"buckets": [
{
"key": "1",
"doc_count": 5,
"noOfParents": {
"doc_count": 5,
"top hits": {
"hits": {
"total": 5,
"max_score": 1,
"hits": [
{
"_shard": "[my-index-2018-12][0]", <-- this is the shard
"_node": "7JNqOhTtROqzQR9QBUENcg",
"_index": "my-index-2018-12",
"_type": "doc",
"_id": "AWdpyZ4Y3HZjlM-Ibd7O",
"_score": 1,
"_source": {
"parent": "A",
"child": {
"id": "1"
}
},
"_explanation": ...
},

另一种证明这是问题根源的方法是将查询隔离在一个碎片中。为此,在搜索请求中添加路由就足够了:?routing=0

这将使您的terms存储桶计数在一个碎片内稳定。然后将noOfParents与预期数量的父级进行比较(同样,在同一碎片内(。

希望能有所帮助!

最新更新