我一直在尝试从反向嵌套聚合中跟踪丢失的文档数。
我的查询
"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的noOfParents。我无意中注意到,如果我将术语聚合的大小更改为50,则noOfParents在此存储桶中正确显示了9。
为什么术语聚合的大小会影响反向聚合的doc_count?这是预期的行为还是错误?我正在使用Elasticsearch 5.6。
答案 0 :(得分:1)
您正在观察的是terms
聚合的最可能的正常行为,因为文档计数是近似的。这既与reverse_nested
无关,也与nested
聚合无关。
简而言之,由于数据分布在各个分片上,因此Elasticsearch首先在每个分片上局部进行最佳猜测,然后将结果合并到各个分片上。有关更好,更详细的说明,请查看this section of the documentation。
要确保确实如此,您可以添加一个top_hits
并启用explain
的聚合:
"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:?routing=0
这将使您的terms
桶的数量在一个分片内保持稳定。然后将noOfParents
与预期的父母数量(同样,在同一分片中)进行比较。
希望有帮助!