cartinality metric
cartinality metric:对每个bucket中的指定的field进行去重,取去重之后的count,类似于count(distinct)
案例
需求: 每月销售品牌的数量统计
1 | GET tvs/sales/_search |
返回值:
1 | { |
先根据月进行分组,然后用cardinality对品牌去重,就ok了
优化准确率和内存开销
precision_threshold
先来看个请求
1 | GET /tvs/sales/_search |
请求中有一个参数 precision_threshold,值是100(默认的就是100),这个搜索请求是根据brand来去重的,precision_threshold的作用就是 如果brand的unique value(去重后的唯一值)在100个以内的话,几乎是100%的准确率的
- precision_threshold:在多少个unique value以内,cardinality会保证几乎100%准确
内存开销
cardinality算法会占用 precision_threshold 8byte 的内存消耗, 比如我们上面这个请求中设置的是100,那么他的内存消耗就是 100 8byte = 800byte ,占用的内存很小.
而且搜索结果中unique value 的数量如果的确在设置的precision_threshold值以内的话,是可以确保100%准确的
官方的说明是如果设置precision_threshold的值是100,实际的unique value有百万的话,错误率是5%以内
HyperLogLog++ (HLL)算法性能优化
cardinality运算的底层算法是HLL算法,如果要优化的话也是去优化HLL算法的性能
会对所有的uqniue value取hash值,通过hash值近似去求distcint count,所以会有一定的误差
默认情况下,发送一个cardinality请求的时候,会动态地对所有的field value取hash值, 我们可以在建立索引的时候,就对字段去设置他的hash值, 就不用去动态的取了
示例
1 | PUT /tvs/ |
索引建立好之后,查询的时候,就需要用brand.hash这个field
1 | GET /tvs/sales/_search |
这种方式其实性能也不会提升多少,可用可不用