Elasticsearch 使用壹種稱為倒排索引的結構,它適用於快速的全文搜索。壹個倒排索引由文檔中所有不重復詞的列表構成,對於其中每個詞,有壹個包含它的文檔列表。
es使用稱為倒排索引的結構達到快速全文搜索的目的。
壹個倒排索引包含壹系列不同的單詞,這些單詞出現在任何壹個文檔,
對於每個單詞,對應著所有它出現的文檔 。
倒排索引建立的是分詞(Term)和文檔(Document)之間的映射關系,在倒排索引中,數據是面向詞(Term)而不是面向文檔的。
例如,假設我們有兩個文檔,每個文檔的content域包含如下內容:
The quick brown fox jumped over the lazy dog
Quick brown foxes leap over lazy dogs in summer
為了創建倒排索引,我們首先將每個文檔的content域拆分成單獨的 詞(我們稱它為詞條或tokens),創建壹個包含所有不重復詞條的排序列表,然後列出每個詞條出現在哪個文檔。結果如下所示:
Term ? Doc_1? Doc_2
-------------------------
Quick? | ? |? X
The |? X? |
brown? |? X? |? X
dog |? X? |
dogs | ? |? X
fox |? X? |
foxes? | ? |? X
in ? | ? |? X
jumped? |? X? |
lazy |? X? |? X
leap | ? |? X
over |? X? |? X
quick? |? X? |
summer? | ? |? X
the |? X? |
------------------------
現在,如果我們想搜索quick brown,我們只需要查找包含每個詞條的文檔:
Term ? Doc_1? Doc_2
-------------------------
brown? |? X? |? X
quick? |? X? |
------------------------
Total? |? 2? |? 1
兩個文檔都匹配,但是第壹個文檔比第二個匹配度更高。如果我們使用僅計算匹配詞條數量的簡單相似性算法,那麽,我們可以說,對於我們查詢的相關性來講,第壹個文檔比第二個文檔更佳。
但是,我們目前的倒排索引有壹些問題:
Quick和quick以獨立的詞條出現,然而用戶可能認為它們是相同的詞。
fox和foxes非常相似, 就像dog和dogs;他們有相同的詞根。
jumped和leap, 盡管沒有相同的詞根,但他們的意思很相近。他們是同義詞。
使用前面的索引搜索+Quick +fox不會得到任何匹配文檔。(記住,+前綴表明這個詞必須存在。)只有同時出現Quick和fox的文檔才滿足這個查詢條件,但是第壹個文檔包含quick fox,第二個文檔包含Quick foxes。
我們的用戶可以合理的期望兩個文檔與查詢匹配。我們可以做的更好。
如果我們將詞條規範為標準模式,那麽我們可以找到與用戶搜索的詞條不完全壹致,但具有足夠相關性的文檔。例如:
Quick可以小寫化為quick。
foxes可以詞幹提取--變為詞根的格式-- 為fox。類似的,dogs可以為提取為dog。
jumped和leap是同義詞,可以索引為相同的單詞jump。
現在索引看上去像這樣:
Term ? Doc_1? Doc_2
-------------------------
brown? |? X? |? X
dog |? X? |? X
fox |? X? |? X
in ? | ? |? X
jump |? X? |? X
lazy |? X? |? X
over |? X? |? X
quick? |? X? |? X
summer? | ? |? X
the |? X? |? X
------------------------
這還遠遠不夠。我們搜索+Quick +fox仍然會失敗,因為在我們的索引中,已經沒有Quick了。但是,如果我們對搜索的字符串使用與content域相同的標準化規則,會變成查詢+quick +fox,這樣兩個文檔都會匹配!