ElastaticSearch 去重cardinality的坑

来源:互联网 发布:vb系列顺序 编辑:程序博客网 时间:2024/06/07 22:43

项目中,Elastatic search(下面简称ES)用于数据存储和分析。

项目中的存储的对象有包含关系。

A对象是B对象的集合,即一个A对象包含多个属于A对象的B对象。在前端展示的时候,需要分别对A和B级别进行查询汇总。设计的时候,考虑到尽可能的减少存储量又能满足各种查询条件,决定以B为单位进行存储,同时B对象拥有属性Aid,用于表示B的归属。

在普通sql数据库中如此存储不会有什么问题,使用distinct可以做到去重查询,通过对Aid的去重能够得到A的数量。ES也支持去重查询,使用cardinality即可。但是,没有想到的是,ES的去重,只有在基数在100-40000之间才可以保证基本的查询准确率。

官方文档的描述如下:

This example will ensure that fields with 100 or fewer distinct values will be extremely accurate. Although not guaranteed by the algorithm, if a cardinality is under the threshold, it is almost always 100% accurate. Cardinalities above this will begin to trade accuracy for memory savings, and a little error will creep into the metric.

For a given threshold, the HLL data-structure will use about precision_threshold * 8 bytes of memory. So you must balance how much memory you are willing to sacri‐ fice for additional accuracy.

Practically speaking, a threshold of 100 maintains an error under 5% even when counting millions of unique values.


结论:ES的去重,同数据库查询的distinct。在基数为100-40000的前提下,能够基本准确。且不管查询的文档量是多少,即便是百万级也能够保证错误率在5%以下。(基数的概念,比如咱们用事务id做去重,查询结果中不同事务id的数量即为基数)。另外,去重的使用更加消耗内存)


目前,笔者尚无有效的解决办法。如有解决方案,恳请赐教。

0 0