Elasticsearch如何檢索數據

咱們都知道Elasticsearch是一個全文檢索引擎,那麼它是如何實現快速的檢索呢?html

傳統的數據庫給每一個字段都存儲成一個單個值,對於全文檢索而言,這樣的存儲是低效的。舉個例子,我有一個大文本字段,存到數據庫裏面只能是一個值,若是想要檢索這個大文本字段裏面的任何一個詞,數據庫如何實現? 只能經過like模糊查詢來實現,先不說性能低,這對於一個搜索引擎是遠遠不夠的。算法

針對上面數據庫的不足,因此纔出現了Lucene這種全文檢索框架而它的核心就在於採用了倒排索引(Inverted Index)的數據結構,不一樣於數據庫的行式存儲,Lucene這裏採用了列式存儲的方式故而對單個字段能夠支持多個值的存儲,這就是倒排索引。數據庫

Term  | Doc 1 | Doc 2 | Doc 3 | ...
------------------------------------
brown |   X   |       |  X    | ...
fox   |   X   |   X   |  X    | ...
quick |   X   |   X   |       | ...
the   |   X   |       |  X    | ...

如上圖所示,倒排索引的一個字段由多個Term組成,這些Term是一個有序的列表,而且是惟一不重複的。對於每個Term又會映射上全部包含該Term的Document Id列表。json

爲何談到Lucene,由於Lucene自己只是一個全文檢索工具包,它不具有企業級的一些特性,如分佈式,副本,擴展等而Elasticsearch和Solr都是基於Lucene開發和擴展的企業級框架,因此瞭解Lucene對學習Elasticsearch和Solr會有很大幫助。緩存

在Elasticsearch中每條數據都是一個json,實際上json中每個字段都有它本身的倒排索引結構。數據結構

固然倒排索引中的每一個Term保存的信息還有不少,好比這個Term在多少個Doucuments裏面出現過的次數,在特定的Doucument裏面出現的次數,每一個Document的length,全部Document的平均length,這些信息是用來計算搜索的相關性(Relevance),咱們都知道使用google和百度搜索結果後,數據會有個前後排名,排名靠前的基本都是最相關的數據,那麼那些因素決定了數據的排名? 這裏面其實就是上面所說的相關性來決定,關於相關性的計算方式也是Lucene裏面的核心功能,目前Lucene裏面主要有兩種Rank算法:框架

(1)經典的基於VSM向量空間的TF/IDF算法elasticsearch

(2)最新的基於機率論的BM25算法分佈式

剛興趣的朋友能夠去維基百科學習一下,這裏再也不展開了。ide

早期的全文檢索全部的數據都會被作成一個大的倒排索引,當新索引準備好以後,它會替代舊的大索引而且最近的變化數據能夠被檢索。

這個大的倒排索引有一個最大的特色就是不可變性,只要索引被寫入磁盤後,就是不可變的:

優勢:

(1)因爲不可變性,因此不須要鎖,也就是不存多個線程同時去修改數據。

(2)能夠直接把索引加載到FileSystem Cache停留在cache中,由於它不會被修改而且FileSystem Cache有足夠大的空間,這樣以來直接在內存中查詢代替在磁盤上,對搜索性能大大提高。

(3)其餘的緩存如filter cache在整個index的生命週期內都是有效的,他們不會被重建,由於索引是不可變的。

(4)不可變的大索引能夠獲得更高的壓縮比,這樣以來可以節省io和佔用的內存資源

缺點:

倒排索引的優勢也是它的缺點,由於它不可變,因此爲了使你新增的數據可以正常的搜索到,你須要重建整個索引,這嚴重限制了單個index存儲的數量以及它的更新頻率。

因此在Elasticsearch中採用了動態更新多個索引方式來解決這個問題,這個會在下篇的文章中介紹。

參考連接:

https://www.elastic.co/guide/en/elasticsearch/guide/master/inverted-index.html

https://www.elastic.co/guide/en/elasticsearch/guide/master/relevance-intro.html

https://www.elastic.co/guide/en/elasticsearch/guide/master/making-text-searchable.html

相關文章
相關標籤/搜索