再Elasticsearch建立索引流程一文中,介紹了ES建立索引的流程。再流程中是調用Lucene的接口來建立索引的。本篇文章主要介紹ES中的索引——倒排索引git
在建立索引以前,會對文檔中的字符串進行分詞。ES中字符串有兩種類型,keyword和text。github
不一樣的分詞器對相同字符串分詞的結果大有不一樣,選擇不一樣的分詞器對索引的建立有很大的影響算法
如拆分「中華人民共和國國歌」sql
ik_max_word分詞器: 最細粒度拆分,分詞結果以下:數據結構
ik_smart分詞器: 最粗粒度的拆分,分詞結果以下:搜索引擎
可見,再ES中建立索引,選擇合適的分詞器是很重要的。spa
- | 單詞1 | 單詞2 | 單詞3 | 單詞4 |
---|---|---|---|---|
文檔1 | √ | √ | ||
文檔2 | √ | |||
文檔3 | √ | |||
文檔4 | √ | √ |
該矩陣是表達單詞和文檔二者之間包含關係的概念模型。
從橫向看,每行表明文檔包含了哪些單詞,好比文檔1包含了單詞1和單詞3,而不包含其它單詞。
從縱向看,每列表明瞭某個單詞存在於哪些文檔。好比單詞1在文檔1和文檔4中出現過。指針
簡單來講,索引就是實現「單詞-文檔矩陣」的具體數據結構,而倒排索引則是實現了這種數據結構的具體方式。code
倒排索引由兩部分構成:排序
它的結構以下:
單詞詞典的特性:
單詞詞典的實現:
單詞詞典有兩種數據結構實現:B+樹和Hash表
B+樹和Mysql索引結構中主鍵索引數據結構同樣,這裏就再也不介紹了
哈希表的key是單詞的hash值,值是單詞的鏈表,由於hash算法會有衝突的狀況發生,因此這裏的值是一個集合,裏面保存着相同hash值得單詞以及改詞指向倒排列表的指針
倒排列表特性:
倒排列表元素數據結構:$$(DocID;TF;<POS>)$$
其中:
有下面單個文檔
- | 內容 |
---|---|
文檔1 | 百度的年度目標 |
文檔2 | AI技術生態部的年度目標 |
文檔3 | AI市場的年度目標 |
則他們生成的倒排索引
單詞ID | 單詞 | 逆向文檔頻率 | 倒排列表(DocID;TF;<POS>) |
---|---|---|---|
1 | 目標 | 3 | (1;1;<3>),(2;1;<5>),(3;1;<4>) |
2 | 年度 | 3 | (1;1;<2>),(2;1;<4>),(3;1;<3>) |
3 | AI | 2 | (2;1;<1>),(3;1;<1>) |
4 | 技術 | 1 | (2;1;<2>) |
5 | 生態 | 1 | (2;1;<3>) |
6 | 市場 | 1 | (3;1;<2>) |
好比單詞「年度」,單詞ID爲2,在三個文檔中出現過,因此逆向文檔頻率爲3,同時倒排索引中的元素也有三個:(1;1;<2>),(2;1;<4>),(3;1;<3>)
。拿第一個元素(1;1;<2>)
進行說明,他表示「年度」再文檔ID爲1的文檔中出現過1次,出現的位置是第二個單詞
直到了倒排索引的內部結構以後,就能很好理解倒排索引的搜索過程了,其內部搜索過程以下圖所示: