购物商城网站建设多少钱,一万元小型办厂设备,宁德seo,短链接在线生成官网参考链接#xff1a;https://blog.csdn.net/u010454030/article/details/71762838 ES group分组聚合的坑 原来知道Elasticsearch在分组聚合时有一些坑但没有细究#xff0c;今天又看了遍顺便做个笔记和大家分享一下。 我们都知道Elasticsearch是一个分布式的搜索引擎#xf…参考链接https://blog.csdn.net/u010454030/article/details/71762838 ES group分组聚合的坑 原来知道Elasticsearch在分组聚合时有一些坑但没有细究今天又看了遍顺便做个笔记和大家分享一下。 我们都知道Elasticsearch是一个分布式的搜索引擎每个索引都可以有多个分片用来将一份大索引的数据切分成多个小的物理索引解决单个索引数据量过大导致的性能问题另外每个shard还可以配置多个副本来保证高可靠以及更好的抗并发的能力。 将一个索引切分成多个shard大多数时候是没有问题的但是在es里面如果索引被切分成多个shard在使用group进行聚合时可能会出现问题这个在官网文档里描述也非常清楚 https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html#_shard_size_3 下面就针对官网的例子描述下group count如果有多个shard可能会出现的问题 假设我们现在我们有一份商品的索引数据它有3个shard每个shard的数据如下所示 现在我们的需求是按商品分组求top5的商品es收到这个请求后会去搜索这三个shard然后子每个shard上面取top5数据如下图所示 最后将三个shard的top5的数据最后做一下汇聚然后最终排序取top5结果如下图 最后我们发现这个top5的结果并不是100%精确的只是一个近似精确的结果值 Product A在所有top5的shard数据里面都存在所以它的结果是精确的 Product C仅仅返回了 shard A 和 C里面的top5的数据所以这里显示50是不精确的 Product C在shard B里面也存在但是它在 top5里面没有出现所以group后的结果实际上是有误差的再来看下 Product Z仅仅返回了2个shards的数据 因为第三个里面不存在所以它的结果是准确的最后我们注意下 Product H实际上它的总数是44横跨三个shard 但是它在每个shard的top5里面并没有出现所以最终的top5里面也没有这条数据这样看来最终的top5的值并不是100% 准确的这一点在设计和使用es的时候需要特别注意。 虽然我们可以调大返回size的个数来提高精确度但是size个数的提升也意味着有更多的数据会被返回从而会导致检索性能的下降这一点是需要找到平衡点的。 那么有没有方法避免这种不精确的统计的呢 答案是有的es官网文档里面也提到总共有2种 第一种 聚合操作在单个shard时是精确的也就是说我们索引的数据全部插入到一个shard的时候 它的聚合统计结果是准确的。 第二种 在索引数据的时候使用route路由字段将所有聚合的数据分布到同一个shard即可这样再聚合时也是精确的。 上面的两种办法都是可以解决的第一种适合数据量不大的场景下我们直接把数据放在一份索引里面第二种办法适合数据量比较大的场景下我们通过业务字段将相同属性的数据路由在同一个shard里面即可具体使用哪个需要和具体的业务场景相结合。 总结 es虽然很强大但是在一些场景下也是有局限的比如上面提到的聚合分组的这个情况或者聚合分组分页的情况此外minmaxsum这些函数在多个shard中聚合结果是准确的count是近似准确的但是es能保证top 前几的数据是精确的这也是为什么搜索引擎一般都返回top n数据作为最终的返回结果当然上面提到那个例子如果聚合的key本来就很少那么它的聚合结果也是准确的比如按性别月份聚合因为这些返回的key都是有限的所以结果没问题但是一旦对分组的个数没法确定这种情况下出现问题的几率就比较大跨表或者跨分片聚合其实在任何db系统里面都会存在这种问题所以我们应该尽量在设计业务时就考虑到这种特殊情况然后最终做特殊处理。转载于:https://www.cnblogs.com/txfsheng/p/9322141.html