概述
繼續跟中華石杉老師學習ES,第50篇
課程位址: https://www.roncoo.com/view/55
思考
聚合分析的内部原理是什麼?當我們使用比如aggs,term,avg 、max等執行一個聚合操作的時候,内部原理是怎樣的呢?用了什麼樣的資料結構去執行聚合?是不是用的反向索引?
知識點
ES搜尋靠反向索引。 排序的時候,需要依靠正排索引,看到每個document的每個field,然後進行排序,所謂的正排索引,其實就是doc values。
ES在建立索引的時候,
- 一方面會建立反向索引,以供搜尋用;
- 一方面會建立正排索引,也就是doc values,以供排序,聚合,過濾等操作使用。
doc values是被儲存在磁盤上的,此時如果記憶體足夠,os會自動将其緩存在記憶體中,性能還是會很高,若記憶體不足,os會将其寫入磁盤。
舉例說明
舉一個 搜尋+聚合 的例子 來了解下 反向索引和正排索引。
GET /test_index/test_type/_search
{
"query": {
"match": {
"search_field": "test"
}
},
"aggs": {
"group_by_agg_field": {
"terms": {
"field": "agg_field"
}
}
}
}
複制
那上面的DSL舉個例子
假設索引中有3個doc
doc1: hello world test1, test2
doc2: hello test
doc3: world test
複制
那ES建立的反向索引如下:
hello ---> doc1,doc2
world ---> doc1,doc3
test1 ---> doc1
test2 ---> doc1
test ---> doc2,doc3
複制
我們的DSL中的查詢
"query": {
"match": {
"search_field": "test"
}
}
複制
查詢 “test” ,那麼直接從反向索引中查到對應的結果為doc2,doc3 ,那麼搜尋就是 doc2,doc3 。
純用反向索引來實作的弊端
先回歸下,最簡單的aggs操作
請求DSL中,
"field": "color"
,按照某個字段劃分bucket操作,
傳回結果是 該field對應的value ,每個value對應一個bucket .
那我們上面的例子中的 aggs呢 ? 假設也是 反向索引的方式來查找,我們來分析下
agg_field
假設如下N多個doc:
...
...
...
...N多doc
doc2: agg_field_value_1
doc3: agg_field_value_2
複制
那建立的反向索引 如下
...
...
...
...
...N多值
agg_field_value_1 doc2
agg_field_value_2 doc3
複制
doc2, doc3, search result --> 實際上,要搜尋到doc2的agg_field的值是多少,doc3的agg_field的值是多少
拿到doc2和doc3的agg_field的值之後,就可以根據值進行分組,實作terms bucket操作
doc2的agg_field的值是多少,這個時候,如果你手上隻有一個反向索引,你該怎麼辦???你要掃描整個反向索引,去一個一個的搜,拿到每個值,比如說agg_field_value_1 ,看一下,它是不是doc2的值,拿到agg_field_value_2,看一下,是不是doc2的值,直到在反向索引中找到doc2的agg_field的值。
如果用純反向索引去實作聚合,現實不現實啊???性能是很低下的。。。搜尋,search,搜反向索引,搜那個term,就結束了。。。聚合,搜尋出了1萬個doc,每個doc都要在反向索引中搜尋出它的那個聚合field的值。
反向索引的話,必須周遊完整個反向索引才可以。。。。
因為可能你要聚合的那個field的值,是分詞的,比如說hello world my name --> 一個doc的聚合field的值可能在反向索引中對應多個value
是以說,當你在反向索引中找到一個值,發現它是屬于某個doc的時候,還不能停,必須周遊完整個反向索引,才能說確定找到了每個doc對應的所有terms,然後進行分組聚合
反向索引+正排索引(doc value)的原理和優勢
正排索引 如下:
document | agg_field |
---|---|
doc1 | agg_fiele_value1 |
doc2 | agg_fiele_value2 |
1萬個doc --> 搜 -> 可能跟搜尋到15000次,就搜尋完了,就找到了1萬個doc的聚合field的所有值了,然後就可以執行分組聚合操作了
石杉老師說的最後一句話 ,我沒明白, 為啥不用把正排索引都搜尋完呢? 有明白的同仁 指導下 拜托了。