技术库 > Java

elasticsearch 聚合结果不准确

技术库:tec.5lulu.com

from:tec.5lulu.com

ES基于分布式,每一个搜索请求都是分发到所有的分片上单独处理,最后汇总结果。聚合也是这样操作。但是在这种逻辑下,会导致某些聚合的结果不准确,即实现group逻辑的terms桶

例子

curl -X GET "localhost:9200/cars/transactions/_search" -H 'Content-Type: application/json' -d'
{
    "size" : 0,
    "aggs" : { 
        "popular_colors" : { 
            "terms" : { 
              "field" : "color",
              "size": 3
            }
        }
    }
} 

这里实现了一个terms聚合,以color为依据进行分组统计。结果为每种color的个数。下面是返回的结果

{
... "hits": { "hits": [] 
   }, "aggregations": { "doc_count_error_upper_bound": 3, "sum_other_doc_count": 10, "popular_colors": "buckets": [
            { "key": "red", "doc_count": 4 
            },
            { "key": "blue", "doc_count": 2
            },
            { "key": "green", "doc_count": 2
            }
         ]
      }
   }
}

在返回结果的aggregations中,有三个值:doc_count_error_upper_bound、sum_other_doc_count和popular_colors。这三个值表示了ES对这次聚合的评估和返回的聚合结果。

  • doc_count_error_upper_bound:表示没有在这次聚合中返回、但是可能存在的潜在聚合结果,这里的值为 3,表除去red、blue和green之外,还可能有一个聚合结果为 3。从返回结果看,可能会排在第二名。
  • sum_other_doc_count:表示这次聚合中没有统计到的文档数。因为ES为分布式部署,不同文档分散于多个分片,这样当聚合时,会在每个分片上分别聚合,然后由协调节点汇总结果后返回。这里因为请求的是排名前三的聚合,所以每个分片只聚合了本分片中排名前三的color。其他没有统计到的文档数由每个节点返回后,汇总为此元素。这里值为 10,表示有10个文档没有参与此次聚合。
  • popular_colors:聚合结果,默认由高到低排列。key表示聚合元素的值,doc_count表示元素出现的次数。注意,这里的doc_count也是不准确的。

由此分析这一次的聚合,虽然返回了top3,但是可能存在另一个第二名,而且doc_count只是一个相对值。
本质上这种误差是由于分布式环境中的数据隔离产生的,尤其是当获取topK数据时,节点内的topK准确不保证整体topK准确。而且无论元素还是元素对应的doc_count,都不是准确的。
所以如果想要ES获取准确的聚合结果,只有max、min、avg等聚合可以做到,而terms API本身不保证准确,只有通过一些额外的方法来确保或者提高准确性:

  1. 不分片,所有数据在一个shard上。这样可以使ES在聚合中使用所有数据,为完全准确。
  2. 在聚合中使用route,将需要聚合的数据路由到同一个节点上。将这样需要数据结构和业务逻辑的支持,一般数据很难实现。
  3. 提高聚合结果的数量。这样可以使每一个分片节点返回更多的冗余数据,在协调节点进行数据汇总时,提高聚合结果的准确性。这种方法只保证聚合结果的近似准确,推荐使用。

elasticsearch 聚合结果不准确


标签: es本文链接 http://tec.5lulu.com/detail/110d8n2ehwgcj85ab.html

我来评分 :6.1
0

转载注明:转自5lulu技术库

本站遵循:署名-非商业性使用-禁止演绎 3.0 共享协议

www.5lulu.com