Elasticsearch中store field與non-store field的區別說明

Elasticsearch中store field與non-store field的區別

在定義index的mapping的時候,我們可以指定某些fields是否要store(默認是不store)

那麼他們有什麼區別呢?

PUT /my_index
{
  "mappings": {
    "my_type": {
      "properties": {
        "title": {
          "type": "string",
          "store": true 
        },
        "date": {
          "type": "date",
          "store": true 
        },
        "content": {
          "type": "string"
        }
      }
    }
  }
}

其實不管你將store設置為ture or false, elasticsearch都將為我們存儲這些field, 不同的是:

  1. 當store為false時(默認配置),這些field隻存儲在”_source” field中。
  2. 當store為true時,這些field的value會存儲在一個跟_source平級的獨立的field中。同時也會存儲在_source中,所以有兩份拷貝。

那麼什麼情況下需要設置store field呢?一般情況有兩種情況:

  • _source field在索引的mapping 中disable瞭。這種情況下,如果不將某個field定義成store=true,那些將無法在返回的查詢結果中看到這個field.
  • _source的內容非常大。這時候如果我們想要在返回的_source document中解釋出某個field的值的話,開銷會很大(當然你也可以定義source filtering將減少network overhead),比例某個document中保存的是一本書,所以document中可能有這些field: title, date, content。假如我們隻是想查詢書的title 跟date信息,而不需要解釋整個_source(非常大),這個時候我們可以考慮將title, date這些field設置成store=true。
  • 需要註意的是,看起來將field store可以減少查詢的開銷,但其實這樣也會加大disk的訪問頻率。假如你將_source中的10個field都定義store,那麼在你查詢這些field的時候會將會有10次disk seek的操作。而返回_source隻有一次disk seek的操作。所以這個也是我們在定義的時候需要blance的。

elasticsearch的store屬性跟_source字段

眾所周知_source字段存儲的是索引的原始內容,那store屬性的設置是為何呢?es為什麼要把store的默認取值設置為no?設置為yes是否是重復的存儲呢?

我們將一個field的值寫入es中,要麼是想在這個field上執行search操作(不知道具體的id),要麼執行retrieve操作(根據id來檢索)。但是,如果不顯式的將該field的store屬性設置為yes,同時_source字段enabled的情況下,你仍然可以獲取到這個field的值。這就意味著在一些情況下讓一個field不被index或者store仍然是有意義的。

當你將一個field的store屬性設置為true,這個會在lucene層面處理。lucene是倒排索引,可以執行快速的全文檢索,返回符合檢索條件的文檔id列表。在全文索引之外,lucene也提供瞭存儲字段的值的特性,以支持提供id的查詢(根據id得到原始信息)。通常我們在lucene層面存儲的field的值是跟隨search請求一起返回的(id+field的值)。es並不需要存儲你想返回的每一個field的值,因為默認情況下每一個文檔的的完整信息都已經存儲瞭,因此可以跟隨查詢結構返回你想要的所有field值。

有一些情況下,顯式的存儲某些field的值是必須的:當_source被disabled的時候,或者你並不想從source中parser來得到field的值(即使這個過程是自動的)。請記住:從每一個stored field中獲取值都需要一次磁盤io,如果想獲取多個field的值,就需要多次磁盤io,但是,如果從_source中獲取多個field的值,則隻需要一次磁盤io,因為_source隻是一個字段而已。所以在大多數情況下,從_source中獲取是快速而高效的。

es中默認的設置_source是enable的,存儲整個文檔的值。這意味著在執行search操作的時候可以返回整個文檔的信息。如果不想返回這個文檔的完整信息,也可以指定要求返回的field,es會自動從_source中抽取出指定field的值返回(比如說highlighting的需求)。

你可以指定一些字段store為true,這意味著這個field的數據將會被單獨存儲。這時候,如果你要求返回field1(store:yes),es會分辨出field1已經被存儲瞭,因此不會從_source中加載,而是從field1的存儲塊中加載。

哪些情形下需要顯式的指定store屬性呢?大多數情況並不是必須的。從_source中獲取值是快速而且高效的。如果你的文檔長度很長,存儲_source或者從_source中獲取field的代價很大,你可以顯式的將某些field的store屬性設置為yes。缺點如上邊所說:假設你存儲瞭10個field,而如果想獲取這10個field的值,則需要多次的io,如果從_source中獲取則隻需要一次,而且_source是被壓縮過的。

還有一種情形:reindex from some field,對某些字段重建索引的時候。從source中讀取數據然後reindex,和從某些field中讀取數據相比,顯然後者代價更低一些。這些字段store設置為yes比較合適。

總結:

如果對某個field做瞭索引,則可以查詢。如果store:yes,則可以展示該field的值。

但是如果你存儲瞭這個doc的數據(_source enable),即使store為no,仍然可以得到field的值(client去解析)。

所以一個store設置為no 的field,如果_source被disable,則隻能檢索不能展示。

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。

推薦閱讀: