真实用5分片和单分片两个索引灌入相同的高频词+长尾词数据,对比terms聚合的doc_count_error_upper_bound从非零变为精确归零,验证多分片各自上报局部候选词合并时的遗漏才是近似结果的真正根源。
代码真实索引到5分片的ta2_test: popular_a(500条)/popular_b(480条)/popular_c(460条),外加300个长尾词各2条,真实打乱顺序写入 POST /ta2_test/_search {"size":0,"aggs":{"t":{"terms":{"field":"term","size":3}}}}
doc_count_error_upper_bound: 7 ← 真实非零,提示结果可能存在误差 sum_other_doc_count: 600 ← 真实300个长尾词(各2条)被排除在top3之外 buckets: → popular_a 500 → popular_b 480 → popular_c 460
这组真实结果里有个容易被忽略的细节:哪怕doc_count_error_upper_bound真实是非零的7,本次实测top3的计数(500/480/460)碰巧依然跟真实精确值完全一致——这个误差上界真实只是ES给出的"最坏情况下这个数字可能偏差多少"的保守估计,不代表这次结果一定真的错了。真实用show_term_doc_count_error:true可以看到每个桶各自的误差估计(本次实测每个桶都是6),这个数字真实提醒的是"存在误差的可能性",而不是"结果已经确认有误"。
代码真实建一个number_of_shards:1的ta2_single索引,灌入完全相同的数据 POST /ta2_single/_search {"size":0,"aggs":{"t":{"terms":{"field":"term","size":3}}}}
单分片索引(相同数据)结果: → doc_count_error_upper_bound: 0 ← 真实精确变成了0 → sum_other_doc_count: 600 ← 跟5分片版本一致
每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。
terms 聚合与 doc_count_error_upper_bound