ES基于分布式,每一個(gè)搜索請(qǐng)求都是分發(fā)到所有的分片上單獨(dú)處理侣夷,最后匯總結(jié)果姐扮。聚合也是這樣操作拳缠。但是在這種邏輯下抚芦,會(huì)導(dǎo)致某些聚合的結(jié)果不準(zhǔn)確,即實(shí)現(xiàn)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
}
}
}
}
這里實(shí)現(xiàn)了一個(gè)terms聚合崩泡,以color為依據(jù)進(jìn)行分組統(tǒng)計(jì)禁荒。結(jié)果為每種color的個(gè)數(shù)。下面是返回的結(jié)果
{
...
"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
}
]
}
}
}
在返回結(jié)果的aggregations中角撞,有三個(gè)值:doc_count_error_upper_bound呛伴、sum_other_doc_count和popular_colors。這三個(gè)值表示了ES對(duì)這次聚合的評(píng)估和返回的聚合結(jié)果谒所。
doc_count_error_upper_bound:表示沒有在這次聚合中返回热康、但是可能存在的潛在聚合結(jié)果,這里的值為 3劣领,表除去red姐军、blue和green之外,還可能有一個(gè)聚合結(jié)果為 3尖淘。從返回結(jié)果看奕锌,可能會(huì)排在第二名。
sum_other_doc_count:表示這次聚合中沒有統(tǒng)計(jì)到的文檔數(shù)村生。因?yàn)镋S為分布式部署惊暴,不同文檔分散于多個(gè)分片,這樣當(dāng)聚合時(shí)梆造,會(huì)在每個(gè)分片上分別聚合缴守,然后由協(xié)調(diào)節(jié)點(diǎn)匯總結(jié)果后返回。這里因?yàn)檎?qǐng)求的是排名前三的聚合镇辉,所以每個(gè)分片只聚合了本分片中排名前三的color屡穗。其他沒有統(tǒng)計(jì)到的文檔數(shù)由每個(gè)節(jié)點(diǎn)返回后,匯總為此元素忽肛。這里值為 10村砂,表示有10個(gè)文檔沒有參與此次聚合。
popular_colors:聚合結(jié)果屹逛,默認(rèn)由高到低排列础废。key表示聚合元素的值,doc_count表示元素出現(xiàn)的次數(shù)罕模。注意评腺,這里的doc_count也是不準(zhǔn)確的。
由此分析這一次的聚合淑掌,雖然返回了top3蒿讥,但是可能存在另一個(gè)第二名,而且doc_count只是一個(gè)相對(duì)值抛腕。
本質(zhì)上這種誤差是由于分布式環(huán)境中的數(shù)據(jù)隔離產(chǎn)生的芋绸,尤其是當(dāng)獲取topK數(shù)據(jù)時(shí),節(jié)點(diǎn)內(nèi)的topK準(zhǔn)確不保證整體topK準(zhǔn)確担敌。而且無論元素還是元素對(duì)應(yīng)的doc_count摔敛,都不是準(zhǔn)確的。
所以如果想要ES獲取準(zhǔn)確的聚合結(jié)果全封,只有max马昙、min、avg等聚合可以做到刹悴,而terms API本身不保證準(zhǔn)確给猾,只有通過一些額外的方法來確保或者提高準(zhǔn)確性:
- 不分片颂跨,所有數(shù)據(jù)在一個(gè)shard上敢伸。這樣可以使ES在聚合中使用所有數(shù)據(jù),為完全準(zhǔn)確恒削。
- 在聚合中使用route池颈,將需要聚合的數(shù)據(jù)路由到同一個(gè)節(jié)點(diǎn)上。將這樣需要數(shù)據(jù)結(jié)構(gòu)和業(yè)務(wù)邏輯的支持钓丰,一般數(shù)據(jù)很難實(shí)現(xiàn)躯砰。
- 提高聚合結(jié)果的數(shù)量。這樣可以使每一個(gè)分片節(jié)點(diǎn)返回更多的冗余數(shù)據(jù)携丁,在協(xié)調(diào)節(jié)點(diǎn)進(jìn)行數(shù)據(jù)匯總時(shí)琢歇,提高聚合結(jié)果的準(zhǔn)確性兰怠。這種方法只保證聚合結(jié)果的近似準(zhǔn)確,推薦使用李茫。