百億級(jí)數(shù)據(jù)全文檢索工具,ElasticSearch鼻祖Lucene

什么是全文檢索?

什么叫做全文檢索呢?這要從我們生活中的數(shù)據(jù)說(shuō)起。我們生活中的數(shù)據(jù)總體分為兩種:
結(jié)構(gòu)化數(shù)據(jù):指具有固定格式或有限長(zhǎng)度的數(shù)據(jù),如數(shù)據(jù)庫(kù),元數(shù)據(jù)等。
非結(jié)構(gòu)化數(shù)據(jù)(也叫全文數(shù)據(jù)) :指不定長(zhǎng)或無(wú)固定格式的數(shù)據(jù),如郵件,word文檔等。
半結(jié)構(gòu)化數(shù)據(jù):如XML,HTML等,當(dāng)根據(jù)需要可按結(jié)構(gòu)化數(shù)據(jù)來(lái)處理,也可抽取出純文本按非結(jié)構(gòu)化數(shù)據(jù)來(lái)處理。

按照數(shù)據(jù)的分類,搜索也分為兩種:
對(duì)結(jié)構(gòu)化數(shù)據(jù)的搜索 :如對(duì)數(shù)據(jù)庫(kù)的搜索,用SQL語(yǔ)句。再如對(duì)元數(shù)據(jù)的搜索,如利用windows搜索對(duì)文件名,類型,修改時(shí)間進(jìn)行搜索等。
對(duì)非結(jié)構(gòu)化數(shù)據(jù)的搜索 :如利用windows的搜索也可以搜索文件內(nèi)容,Linux下的grep命令,再如用Google和百度可以搜索大量?jī)?nèi)容數(shù)據(jù)。

對(duì)非結(jié)構(gòu)化數(shù)據(jù)也即對(duì)全文數(shù)據(jù)的搜索主要有兩種方法:
順序掃描法 (Serial Scanning)
所謂順序掃描,比如要找內(nèi)容包含某一個(gè)字符串的文件,就是一個(gè)文檔一個(gè)文檔的看,對(duì)于每一個(gè)文檔,從頭看到尾,如果此文檔包含此字符串,則此文檔為我們要找的文件,接著看下一個(gè)文件,直到掃描完所有的文件。如利用windows的搜索也可以搜索文件內(nèi)容,只是相當(dāng)?shù)穆?。如果你有一個(gè)80G硬盤,如果想在上面找到一個(gè)內(nèi)容包含某字符串的文件,不花他幾個(gè)小時(shí),怕是做不到。Linux下的grep命令也是這一種方式。
這種方法比較原始,但對(duì)于小數(shù)據(jù)量的文件,這種方法還是最直接,最方便的。但是對(duì)于大量的文件,這種方法就很慢了。
全文檢索
將非結(jié)構(gòu)化數(shù)據(jù)中的一部分信息提取出來(lái),重新組織,使其變得有一定結(jié)構(gòu),然后對(duì)此有一定結(jié)構(gòu)的數(shù)據(jù)進(jìn)行搜一個(gè)索,從而達(dá)到搜索相對(duì)較快的目的。

Apache Lucene是什么?

Apache Lucene其實(shí)就是apache提供的一個(gè)開(kāi)源關(guān)于搜索引擎的類庫(kù),囊括了較為全面的有關(guān)搜索引擎相關(guān)的技術(shù)解決思路,使得現(xiàn)如今的soler以及ElasticSearch尤為的火爆,不管是在互聯(lián)網(wǎng)項(xiàng)目中以及大數(shù)據(jù)領(lǐng)域占據(jù)了不可多得的地位。

索引

正排索引

正排索引.png

為什么順序掃描的速度慢:其實(shí)是由于我們想要搜索的信息和非結(jié)構(gòu)化數(shù)據(jù)中所存儲(chǔ)的信息不一致造成的。

倒排索引

非結(jié)構(gòu)化數(shù)據(jù)中所存儲(chǔ)的信息是每個(gè)文件包含哪些字符串,也即已知文件,欲求字符串相對(duì)容易,也即是從文件到字符串的映射。而我們想搜索的信息是哪些文件包含此字符串,也即已知字符串,欲求文件,也即從字符串到文件的映射。兩者恰恰相反。于是如果索引總能夠保存從字符串到文件的映射,則會(huì)大大提高搜索速度。


倒排索引.png

倒排索引一般表示為一個(gè)關(guān)鍵詞,然后是它的頻度(出現(xiàn)的次數(shù)),位置(出現(xiàn)在哪一篇文章或網(wǎng)頁(yè)中,及有關(guān)的日期,作者等信息),它相當(dāng)于為互聯(lián)網(wǎng)上幾千億頁(yè)網(wǎng)頁(yè)做了一個(gè)索引,好比一本書的目錄、標(biāo)簽一般。想看哪一個(gè)主題相關(guān)的章節(jié),直接根據(jù)目錄即可找到相關(guān)的頁(yè)面。不必再?gòu)臅牡谝豁?yè)到最后一頁(yè),一頁(yè)一頁(yè)的查找。

例如:
文章 head content
文章1 超級(jí)塞亞人 我是超級(jí)塞亞人我喜歡吃蘋果,我不是天朝的人,也不是地球人
文章2 天朝大國(guó) 我大天朝威武,我大天朝13億人,我大天朝
文章3 游泳 游泳有很多好方法
文章4 動(dòng)畫片 喜歡看動(dòng)畫片,尤其是七龍珠,因?yàn)槔锩嬗腥麃喨?,而且塞亞人喜歡吃蘋果,他們不是地球人
文章5 運(yùn)動(dòng) 喜歡運(yùn)動(dòng),喜歡跑步,喜歡游泳,喜歡健身,喜歡
文章6 打炮 我喜歡打游戲,我最幸福的時(shí)光就是在天朝吃著蘋果玩打炮游戲

關(guān)鍵字:塞亞人 蘋果 天朝 地球 七龍珠 游泳 喜歡

關(guān)鍵詞 索引
塞亞人 文章1[1],文章4[2], n n n
蘋果 文章1[1],文章4[1],文章6[1], n n n
天朝 文章1[1],文章2[2],文章6[1], n n n n
地球 文章1[1],文章4[1], n n
游泳 文章3[1],文章5[1], n n
七龍珠 文章4[1], n
喜歡 文章1[1],文章4[2],文章5[4],文章6[1], n n n n n n n n

倒排索引2個(gè)重要構(gòu)成:
1.倒排文件(inverted file):存儲(chǔ)倒排索引的物理文件
2.倒排索引組成:?jiǎn)卧~詞典和倒排文件。

何為倒排索引

核心術(shù)語(yǔ)

倒排索引.png

Index
Lucene的索引(Index)是由多個(gè)文件組成,這些文件被存放在同一目錄下。
Token
詞元(Token)在Lucene與在自然語(yǔ)言處理(NLP)中的概念相同,表示“詞元”。詞元即自然語(yǔ)言中的基本單位:在中文表現(xiàn)為一個(gè)獨(dú)立的字或詞,在英文中表現(xiàn)為一個(gè)單詞。
Term
經(jīng)過(guò)分詞和語(yǔ)言處理后得到的字符串,它是索引的最小單位。
Field
不同的域可以指定不同的索引方式,比如指定不同的分詞方式,是否構(gòu)建索引,是否存儲(chǔ)等。
Document
文檔是索引的基本單位,代表一些域(Field)的集合。在Lucene中,Document是一種邏輯文件。可以近似地認(rèn)為它表示的是計(jì)算機(jī)中的一個(gè)文件。這個(gè)Document是一種抽象的表示,它從各種維度來(lái)描述一個(gè)數(shù)據(jù)源中的每一條數(shù)據(jù)。
可以使用關(guān)系型數(shù)據(jù)庫(kù)中的記錄來(lái)理解Document,數(shù)據(jù)庫(kù)的每一條記錄可以表示為一個(gè)Document,而每一列可以用Field來(lái)表示。但不同的是,Document并非結(jié)構(gòu)化的,并沒(méi)有schema的約束。不同的文檔保存在不同的段中的,一個(gè)段中可以包含多篇文檔。新添加的文檔被單獨(dú)保存在一個(gè)新生成的段中,隨著段的合并,不同的文檔會(huì)合并到至相同的段中。
Segment
一個(gè)Lucene的索引(Index)由多個(gè)段組成,段與段之間是獨(dú)立的。當(dāng)添加索引時(shí)會(huì)生成新的Document,但并不是把新的Document 立即添加到同一個(gè)索引文件,而是把它們先被寫入到不同的小文件(Segment),當(dāng)小文件的個(gè)數(shù)達(dá)到閾值(段的個(gè)數(shù),段中包含的文件數(shù)等)時(shí),然后再合并成一個(gè)大索引文件(不同的段可以合并)。
Directory
Lucene索引的存放位置。
文檔模型

文檔名稱 擴(kuò)展名 說(shuō)明
Segments File segments_N 保存提交點(diǎn)的信息
Lock File write.lock 寫文件鎖,用于防止多個(gè)IndexWriters同時(shí)寫一個(gè)文件
Segment Info .si 保存段的元數(shù)據(jù)信息
Compound File .cfs, .cfe 采用混合格式下該文件包括其他所有格式的文件
Fields .fnm 保存域信息
Field Index .fdx 保存指向域數(shù)據(jù)的指針
Field Data .fdt 保存域數(shù)據(jù)
Term Dictionary .tim 保存詞項(xiàng)信息
Term Index .tip Term Dictionary的索引信息
Frequencies .doc 記錄文檔信息,以及文檔中詞項(xiàng)對(duì)應(yīng)的詞頻
Positions .pos 記錄詞項(xiàng)的位置信息
Payloads .pay 全文索引的字段,使用了一些像payloads的高級(jí)特性會(huì)有該文件,保存了term在doc中的一些高級(jí)特性
Norms .nvd, .nvm 文件保存索引字段加權(quán)數(shù)據(jù)
Per-Document Values .dvd, .dvm lucene的docvalues文件,即數(shù)據(jù)的列式存儲(chǔ),用作聚合和排序
Term Vector Index .tvx 記錄文檔數(shù)據(jù)記錄中的偏移量
Term Vector Documents .tvd 記錄有詞項(xiàng)向量的文檔的信息
Term Vector Fields .tvf 詞項(xiàng)向量的域級(jí)別信息
Live Documents .liv 存活文件的信息
Point values .dii, .dim 記錄被索引的點(diǎn)

Segment_N
Segments_N為段的元數(shù)據(jù)信息文件。保存了此索引包含多少個(gè)段,每個(gè)段包含多少篇文檔等信息。

Segment_N.png

Lucene當(dāng)前活躍的Segment都會(huì)存在一個(gè)Segment Info文件里,也就是segments_N。如果有多個(gè)segments_N, 那么序號(hào)最大的就是最新的。
1.Format:索引文件格式的版本號(hào)。由于Lucene是在不斷開(kāi)發(fā)過(guò)程中的,不同版本的Lucene可能有不同索引文件格式,所以規(guī)定了文件格式的版本號(hào)。
2.Version:索引的版本號(hào)
3.NameCount:下一個(gè)新段的段名
4.SegCount:段的個(gè)數(shù)
[Lucece圖形化工具Luke:]{https://www.github.com/DmitryKey/luke}
域文件格式
域元數(shù)據(jù)文件(fnm)
一個(gè)段(Segment)包含多個(gè)域,每個(gè)域都有一些元數(shù)據(jù)信息,保存在.fnm文件中,.fnm文件的格式如下:
域文件格式.png

域的數(shù)據(jù)信息存儲(chǔ)在 .fdt 和 .fdx 文件中。其中,.fdx 文件中存放FieldValuesPositon,指向.fdt文件,也就是說(shuō)域的具體數(shù)據(jù)是存放在fdt文件中的。
域數(shù)據(jù)文件(fdt)
真正保存域(stored field)信息的是fdt文件。
假如在一個(gè)Segment中包含N篇文檔,那么fdt文檔中一會(huì)有N個(gè)項(xiàng),每一個(gè)項(xiàng)都保存對(duì)應(yīng)文檔的域信息。
FieldCount,表示此文檔包含的域數(shù)目
緊接著是FieldCount域信息項(xiàng),每個(gè)項(xiàng)保存一個(gè)域的信息。對(duì)于每一個(gè)域的信息:
FieldNum是域編號(hào)
接著是一個(gè)8bit的byte。根據(jù)填充值(0或1),代表不同的意義。最低一位表示此域是否分詞;倒數(shù)第二位表示此域保存的是字符串?dāng)?shù)據(jù)還是二進(jìn)制數(shù)據(jù);倒數(shù)第三位表示此域是否被壓縮。最后存儲(chǔ)的是這個(gè)存儲(chǔ)域的值。
域索引文件(fdx)
由域數(shù)據(jù)文件格式可知,每篇文檔包含的域的個(gè)數(shù)、每個(gè)存儲(chǔ)域的值都是不一樣的。
因?yàn)閟egment中會(huì)包含N篇文檔(Document),每篇文檔占用的大小也是不一樣的,那么如何快速在fdt文件中辨別每一篇文檔的起始地址和終止地址?如何能夠更快的找到第N篇文檔的存儲(chǔ)域的信息呢?
這就需要借助域索引文件。域索引文件也總共有N個(gè)項(xiàng)(如果segment中包含N篇Document),每篇文檔都對(duì)應(yīng)一個(gè)項(xiàng),每一項(xiàng)中都存儲(chǔ)一個(gè)Long型數(shù)值(大小固定),該數(shù)值代表文檔在fdt中的起始地址偏移量。
域索引文件格式.png

詞向量文件
詞向量信息是從索引(Index)到文檔(Document)到域(Field)到詞(Term)的正向信息,有了詞向量信息,就可以得到一篇文檔包含哪些詞的信息 。
詞向量文件格式.png

詞向量數(shù)據(jù)文件(tvd)
首先,是此文檔包含域的個(gè)數(shù):NumFields
之后,是一個(gè)NumFields大小的數(shù)組,數(shù)組每一項(xiàng)都是域號(hào)
最后,是(NumField - 1)大小的數(shù)組。每一篇文檔的第一個(gè)域的偏移量信息存儲(chǔ)在 tvx 文件中。而其他(NumFields - 1)域的偏移量就是第一個(gè)域的偏移量加上第(NumField - 1)個(gè)數(shù)組的值。
詞向量索引文件(tvx)
一個(gè)段(segment)包含N篇文檔,此文件就有N項(xiàng),每一項(xiàng)代表一篇文檔。每一項(xiàng)包含兩部分信息:
第一部分是詞向量文檔文件(tvd)中此文檔的偏移量
第二部分是詞向量文件(tvf)中此文檔的第一個(gè)域的偏移量
詞向量域文件(tvf)
該文件包含了此段(Segment)中的所有域,并且不對(duì)文檔做區(qū)分,到底第幾個(gè)域到第幾個(gè)域是屬于那篇文件,是由tvx文件中的第一個(gè)域的偏移量以及tvd文件中的(NumField - 1)個(gè)域的偏移量來(lái)決定哪些域數(shù)據(jù)屬于哪個(gè)文檔。
對(duì)于每一個(gè)域,包含如下項(xiàng):
首先,是說(shuō)明此域中包含的多少(NumTerms)個(gè)詞(Term)
之后,是8bit的byte(最后一位指定是否保存位置信息,倒數(shù)第二位表示是否保存偏移量信息)
最后,NumTerms個(gè)項(xiàng)的數(shù)組,每一項(xiàng)代表一個(gè)詞(Term)。每一個(gè)詞,由如下幾部分構(gòu)成
詞的文本TermText
詞頻TermFreq(詞在該文檔中出現(xiàn)的次數(shù))
詞的位置
詞的偏移量

創(chuàng)建倒排索引流程


全文檢索的索引創(chuàng)建過(guò)程一般有以下幾步:
第一步(原始素材)
為了方便說(shuō)明索引創(chuàng)建過(guò)程,這里特意用兩個(gè)文件為例:
文件一:Students should be allowed to go out with their friends, but not allowed to drink beer.
文件二:My friend Jerry went to school to see his students but found them drunk which is not allowed.
第二步(分詞)
將原文檔傳給分詞器(Tokenizer),分詞器會(huì)做以下幾件事情( 此過(guò)程稱為Tokenize) :
將文檔分成一個(gè)一個(gè)單獨(dú)的單詞。
去除標(biāo)點(diǎn)符號(hào)。
去除停詞(Stop word) 。
所謂停詞(Stop word)就是一種語(yǔ)言中最普通的一些單詞,由于沒(méi)有特別的意義,因而大多數(shù)情況下不能成為搜索的關(guān)鍵詞,因而創(chuàng)建索引時(shí),這種詞會(huì)被去掉而減少索引的大小。
每一種語(yǔ)言的分詞組件(Tokenizer),都有一個(gè)停詞(stop word)集合。
經(jīng)過(guò)分詞(Tokenizer) 后得到的結(jié)果稱為詞元(Token) ,如下:
第三步(語(yǔ)言處理)
將得到的詞元(Token)傳給語(yǔ)言處理組件(Linguistic Processor),語(yǔ)言處理組件(linguistic processor)主要是對(duì)得到的詞元(Token)做一些同語(yǔ)言相關(guān)的處理。
對(duì)于英語(yǔ),語(yǔ)言處理組件(Linguistic Processor) 一般做以下幾點(diǎn):
變?yōu)樾?Lowercase) 。
將單詞縮減為詞根形式,如“cars ”到“car ”等。這種操作稱為:stemming 。
將單詞轉(zhuǎn)變?yōu)樵~根形式,如“drove ”到“drive ”等。這種操作稱為:lemmatization 。
經(jīng)過(guò)語(yǔ)言處理,得到的詞(Term)如下:
第四步(構(gòu)建索引)
至此,Lucene有關(guān)于搜索引擎以及基礎(chǔ)知識(shí)點(diǎn)還有如何創(chuàng)建索引和大家分享完,歡迎大家和我一起分享學(xué)習(xí)!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Lucene 官網(wǎng) 1). 概述 Lucene是一款高性能的、可擴(kuò)展的信息檢索(IR)工具庫(kù)。信息檢索是指文...
    _凌浩雨閱讀 1,004評(píng)論 0 1
  • 目錄結(jié)構(gòu):1.全文檢索 2.Lucene入門3.Lucene進(jìn)階 全文檢索 一, 生活中的搜索:1.Win...
    CoderZS閱讀 1,798評(píng)論 0 12
  • 1. 案例分析:什么時(shí)全文檢索,如何實(shí)現(xiàn)全文檢索 ? 1.1 案例 ? 實(shí)現(xiàn)一個(gè)文件的搜索功能,通過(guò)關(guān)鍵字搜索文件...
    東方舵手閱讀 1,230評(píng)論 0 1
  • ORA-00001: 違反唯一約束條件 (.) 錯(cuò)誤說(shuō)明:當(dāng)在唯一索引所對(duì)應(yīng)的列上鍵入重復(fù)值時(shí),會(huì)觸發(fā)此異常。 O...
    我想起個(gè)好名字閱讀 5,920評(píng)論 0 9
  • 12點(diǎn),一輛輛景區(qū)觀光車已整裝待發(fā),我們是最先幾批上的,繞過(guò)幾條街道,就往效外前進(jìn)!沿路不斷見(jiàn)到被推到一半的廢棄民...
    西泠靜閱讀 406評(píng)論 0 0

友情鏈接更多精彩內(nèi)容