天天看點

白話Elasticsearch50-深入聚合資料分析之基于doc values正排索引的聚合内部原理概述思考知識點舉例說明

白話Elasticsearch50-深入聚合資料分析之基于doc values正排索引的聚合内部原理概述思考知識點舉例說明

概述

繼續跟中華石杉老師學習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操作

白話Elasticsearch50-深入聚合資料分析之基于doc values正排索引的聚合内部原理概述思考知識點舉例說明

請求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的所有值了,然後就可以執行分組聚合操作了

石杉老師說的最後一句話 ,我沒明白, 為啥不用把正排索引都搜尋完呢? 有明白的同仁 指導下 拜托了。