聚合使用一個叫 doc values 的數據結構(在 Doc Values 介紹 裏簡單介紹)。 Doc values 可使聚合更快、更高效而且內存友好,因此理解它的工做方式十分有益。html
Doc values 的存在是由於倒排索引只對某些操做是高效的。 倒排索引的優點 在於查找包含某個項的文檔,而對於從另一個方向的相反操做並不高效,即:肯定哪些項是否存在單個文檔裏,聚合須要這種次級的訪問模式。數據結構
對於如下倒排索引:elasticsearch
Term Doc_1 Doc_2 Doc_3 ------------------------------------ brown | X | X | dog | X | | X dogs | | X | X fox | X | | X foxes | | X | in | | X | jumped | X | | X lazy | X | X | leap | | X | over | X | X | X quick | X | X | X summer | | X | the | X | | X ------------------------------------
若是咱們想要得到全部包含 brown
的文檔的詞的完整列表,咱們會建立以下查詢:ide
GET /my_index/_search { "query" : { "match" : { "body" : "brown" } }, "aggs" : { "popular_terms": { "terms" : { "field" : "body" } } } }
查詢部分簡單又高效。倒排索引是根據項來排序的,因此咱們首先在詞項列表中找到 brown
,而後掃描全部列,找到包含 brown
的文檔。咱們能夠快速看到 Doc_1
和 Doc_2
包含 brown
這個 token。ui
而後,對於聚合部分,咱們須要找到 Doc_1
和 Doc_2
裏全部惟一的詞項。 用倒排索引作這件事情代價很高: 咱們會迭代索引裏的每一個詞項並收集 Doc_1
和 Doc_2
列裏面 token。這很慢並且難以擴展:隨着詞項和文檔的數量增長,執行時間也會增長。code
Doc values 經過轉置二者間的關係來解決這個問題。倒排索引將詞項映射到包含它們的文檔,doc values 將文檔映射到它們包含的詞項:htm
Doc Terms ----------------------------------------------------------------- Doc_1 | brown, dog, fox, jumped, lazy, over, quick, the Doc_2 | brown, dogs, foxes, in, lazy, leap, over, quick, summer Doc_3 | dog, dogs, fox, jumped, over, quick, the -----------------------------------------------------------------
當數據被轉置以後,想要收集到 Doc_1
和 Doc_2
的惟一 token 會很是容易。得到每一個文檔行,獲取全部的詞項,而後求兩個集合的並集。排序
所以,搜索和聚合是相互緊密纏繞的。搜索使用倒排索引查找文檔,聚合操做收集和聚合 doc values 裏的數據。索引
Doc values 不只能夠用於聚合。 任何須要查找某個文檔包含的值的操做都必須使用它。 除了聚合,還包括排序,訪問字段值的腳本,父子關係處理(參見 父-子關係文檔 )。token