elasticsearch基于全文檢索引擎Lucene,Apache給出的官方定義:Lucene是高效的基于java的全文檢索庫。
順序掃描方法:顧名思義就是按照順序從頭到尾進(jìn)行檢索 grep命令就是如此,
-
全文檢索:如果是結(jié)構(gòu)化的數(shù)據(jù)可以采用某些算法提升搜索速度。那我們可以把非結(jié)構(gòu)化的數(shù)據(jù)中的結(jié)構(gòu)化部分抽取出來,重新組織,從而達(dá)到快速檢索的目的。
全文檢索:分為2步:
第一步:創(chuàng)建索引
第二步:搜索索引
正向索引:從文檔中查找字符串,關(guān)系型數(shù)據(jù)庫使用的是正向索引
反向索引:從字符串中查找文檔 搜索引擎Lucene使用的是反向索引
何為反向索引呢?
1558668168(1).jpg 如上圖所示,假如我有100個(gè)文檔,對(duì)他們從1-100進(jìn)行編號(hào);
左邊保存的是一系列的字符串,也可以理解為詞,我們稱這些字符串集合為詞典;
右邊保存的是包含左邊字符串的文檔鏈表,此文檔鏈表成為倒排表
在上面中,我們對(duì)詞典中包含的字符串創(chuàng)建索引,而這些字符串也正是我們搜索的信息,因此可以大大加快查詢速度。
如果查詢包含hadoop和lucene的文檔:
第一步:取出包含lucene的文檔鏈表
第二步:取出包含hadoop的文檔鏈表
第三步:合并鏈表,取出交集

索引的創(chuàng)建一般分為以下幾步:
第一步:將文檔交給切詞組件(Tokenizer)進(jìn)行切詞處理
第二步:將得到的詞元(Token)交給語言處理組件
第三步:將得到的詞(Term)交給索引組件
第四步:由索引組件針對(duì)詞建立索引
針對(duì)上述步驟,我們給出2個(gè)示例文檔,加以詳細(xì)說明
Document 1:Students should be allowed to go out with their friends, but not allowed to drink beer.
Document 2:My friend Jerry went to school to see his students but found them drunk which is not allowed.
第一步:切詞組件處理
上述2個(gè)文檔會(huì)被交給切詞組件,切詞組件主要針對(duì)文檔進(jìn)行切割,將文檔中的單詞一個(gè)一個(gè)切割出來,同時(shí)消除一些無意義的詞,比如標(biāo)點(diǎn)符號(hào)、英文中的the和is、中文中的的等。因?yàn)闃?biāo)點(diǎn)符號(hào)和一些形容詞,在實(shí)際的搜索中是很少會(huì)被搜索的,所以在該步驟會(huì)剃掉這些詞語,減少索引的大小
經(jīng)過切割以后,可能會(huì)被切分成以下詞元:
“Students”,“allowed”,“go”,“their”,“friends”,“allowed”,“drink”,“beer”,“My”,“friend”,“Jerry”,“went”,“school”,“see”,“his”,“students”,“found”,“them”,“drunk”,“allowed”
第二步:語言處理組件處理
該步驟主要針對(duì)第一步生成的詞元進(jìn)行自然語言同化處理,比如針對(duì)cars詞元,同時(shí)生成新的詞car;Student詞元中的大寫字母小寫化,這樣能夠?qū)崿F(xiàn)一個(gè)student搜索,可以同時(shí)搜索處理像Student、STUDENT、stuDENT等多種情況,經(jīng)過該步驟處理后,可能會(huì)被切分成以下詞:
“student”,“allow”,“go”,“their”,“friend”,“allow”,“drink”,“beer”,“my”,“friend”,“jerry”,“go”,“school”,“see”,“his”,“student”,“find”,“them”,“drink”,“allow”
正因?yàn)橛辛俗匀徽Z言處理組件,才能使得搜索drove,drive也能被搜出來
第三步:將得到的詞交給索引組件建立索引
(1)、利用得到的詞創(chuàng)建一個(gè)詞典

(2)、對(duì)字典按字母順序進(jìn)行排序

(3)、合并相同的詞并建立倒排鏈表

在上述表中,有幾個(gè)定義:
Document Frequency:表示該詞出現(xiàn)在所有文檔的總數(shù)
Frequency:表示在某一個(gè)文檔中該詞出現(xiàn)的次數(shù)
第四步:建立索引
針對(duì)最后生成的詞典,進(jìn)行索引的建立,至此我們發(fā)現(xiàn)根據(jù)搜索詞,我們可以立即找到對(duì)應(yīng)的文檔;而且諸如drink、drunk等都可以找到同一個(gè)文檔
問題3:如何對(duì)索引進(jìn)行搜索?
搜索可以分為以下幾步:
第一步:用戶輸入查詢語句
第二步:對(duì)查詢語句進(jìn)行詞法分析、語法分析、語言處理
第三步:搜索索引,得到符合語法樹的文檔
第四步:根據(jù)得到的文檔和查詢語句相關(guān)性,對(duì)結(jié)果進(jìn)行排序予以展示
第一步:用戶輸入語句
查詢語句的語法根據(jù)全文檢索系統(tǒng)的實(shí)現(xiàn)而不同。
比如用戶輸入:lucene AND learned NOT hadoop --------- 用戶想要查找包含lucene和learned,但是不包含hadoop的文檔
第二步:對(duì)查詢語句進(jìn)行詞法分析、語法分析、語言處理
(1)、詞法分析主要用來識(shí)別單詞和關(guān)鍵字
比如針對(duì)上述用戶的輸入,經(jīng)過詞法分析,得到單詞為lucene、learned、hadoop,關(guān)鍵詞為AND、NOT
(2)、語言分析主要根據(jù)查詢語句來生成一顆語法樹
受限進(jìn)行語法判斷,如果不滿足語法要求,則直接報(bào)錯(cuò);若滿足語法要求,則可以生成下面的語法樹:

(3)、語言處理和索引建立過程中得語言處理幾乎一樣
例如將learned變成learn,經(jīng)過處理后得到以下結(jié)果:

第三步:搜索索引,得到符合語法樹得文檔
首先,在反向索引鏈表里,找到包含lucene、learn和hadoop得文檔
其次,對(duì)包含lucene和learn得文檔進(jìn)行求合集操作,得到同時(shí)包含兩者得文檔鏈條
然后,將得到合集后得鏈表與hadoop得文檔鏈表進(jìn)行差集操作,去除包含hadoop得文檔
最后,此文檔鏈表就是我們要找得文檔
第四步:根據(jù)得到的文檔和查詢語句的相關(guān)性,對(duì)結(jié)果進(jìn)行排序
此過程也是極其復(fù)雜的,比如谷歌搜索,查詢出來的結(jié)果有幾十萬上百萬,如何排序顯示,這個(gè)過程涉及到一些自然語言的理解,過程非常復(fù)雜,在此不再贅述
總結(jié):Lucene是一個(gè)開源的分部署搜索引擎的實(shí)現(xiàn),ElasticSearch底層就是基于Lucene實(shí)現(xiàn)的,之所以能夠?qū)崿F(xiàn)分布式搜索,原因就在于每一個(gè)文檔在出庫入庫之前,就已經(jīng)被進(jìn)行切詞分析處理,針對(duì)每個(gè)詞建立索引,是一種空間換時(shí)間的做法
