在elasticsearch中,我总是在doc_count_error_upper_bound
属性上得到一个很高的聚合查询值。对于一个索引了近十亿个文档的ES集群来说,它有时会高达8000或9000。我在一个大约5M文档的索引上运行查询,得到的值大约是300到500。
问题是我的结果有多不正确(我正在尝试基于下面的JSON的前20个计数查询)
"aggs":{ "group_by_creator":{ "terms":{ "field":"creator" } } } }
在elasticsearch中,我总是在doc_count_error_upper_bound
属性上得到一个很高的聚合查询值。对于一个索引了近十亿个文档的ES集群来说,它有时会高达8000或9000。我在一个大约5M文档的索引上运行查询,得到的值大约是300到500。
问题是我的结果有多不正确(我正在尝试基于下面的JSON的前20个计数查询)
"aggs":{ "group_by_creator":{ "terms":{ "field":"creator" } } } }
4条答案
按热度按时间ny6fqffe1#
这在官方文档中有很好的解释。
当运行
terms
聚合时,每个分片将计算出自己的前20个术语列表,然后返回它们的前20个术语。协调节点将收集所有这些术语并对其进行重新排序,以获得所有分片的前20个术语。如果您有多个分片,那么可能会出现非零错误计数(如官方文档示例所示)并不奇怪,并且有一种方法可以计算文档计数错误。
每个索引使用一个分片,文档错误计数将始终为零,但根据索引拓扑,这可能并不总是可行的,特别是如果您有近十亿个文档。但是对于500万文档的索引,如果它们不是很大,它们很可能存储在单个分片中。当然,这在很大程度上取决于您的硬件,但如果您的分片大小不超过15/20 GB,您应该没问题。你应该尝试用一个分片创建一个新的索引,看看效果如何。
eqoofvh92#
我创造了这个可视化来尝试自己理解它。
有两个级别的聚合错误:
第一个函数给出了聚合的一个整体值,它表示未进入最终术语列表的术语的最大潜在文档计数。
和
第二个显示聚合返回的每个项的错误值,它表示文档计数中最坏情况的错误,在决定shard_size参数的值时可能很有用。这是通过对所有没有返回该词的分片返回的最后一个词的文档计数求和来计算的。
您可以通过设置来查看术语级别错误:
虽然默认情况下显示整体聚合错误,
标签:official docs
jm81lzqq3#
添加到其他(精细)答案:
您可以通过增加
shard_size
-参数来最小化error_count,如下所示:这是干什么的?
当你请求一个terms-aggregation时,elastic会将其传递给各个分片,然后重新组合结果。例如,它可能看起来像这样(尽管我为了简洁而缩小了它):
A: 10, B: 8, C:6, D:4, E:2
A: 12, C:8, F: 5, B: 4, G: 4
协调节点将其相加为:
这意味着协调节点可以返回一个top-3,这是保证准确的,但top-5将有一个
doc_count_error_upper_bound
为4,因为我们错过了一些数据。为了防止这个问题,弹性实际上可以要求每个分片报告更多的术语。如您所见,如果我们只想要一个top-3,那么请求每个分片报告它们的top-5就解决了这个问题。为了获得准确的前5名,要求每个分片发送他们的前10名可能已经解决了我们的问题。
这就是
shard_size
所做的:它要求每个节点报告更大量的术语,这样我们就有希望得到足够术语的报告,以降低错误率。虽然它的代价是每个节点都需要一些处理,所以如果你有很多文档,将它设置为一个荒谬的值,比如int.MaxValue
(就像另一个答案所建议的那样)是一个非常糟糕的主意。为什么elastic本身还没有做到这一点?
惊喜:是的。这并不总是足够的,但是如果你用这个值进行实验,你会发现你可以得到更糟糕的结果。默认情况下(如文档中所述),它使用
size * 1.5 + 10
,默认的top-10的值为25,或者您的用例为40。plupiseo4#
将shardSize设置为int.MaxValue,这将减少计数错误