《lucene in action》筆記:構(gòu)建索引

1.lucene如何對搜索內(nèi)容進行建模

1.1文檔(document)和域(field)

文檔是lucene索引和搜索的原子單位。文檔為包含一個或多個域的容器,而域則依次包含真正的被搜索的內(nèi)容。比如一篇文章就是一個文檔,標題是一個域,標題內(nèi)容為域值,正文也是一個域,正文內(nèi)容為域值。lucene可以針對域進行三種操作:

  • 域值可以被索引
  • 域被索引后,可以選擇性的存儲項向量。項向量(TermVector)可以被用作相似查找
  • 域值還可以被單獨存儲

2.理解索引過程

2.1提取文本和創(chuàng)建文檔

使用lucene索引數(shù)據(jù)時,必須先從數(shù)據(jù)中提取純文本格式信息,以便lucene識別該文本并建立對應的lucene文檔。tika框架可以輕易的從各種格式的文件中提取文本信息

2.2分析文檔

一旦建立起lucene文檔和域,就可以調(diào)用IndexWriter對象的addDocument方法將數(shù)據(jù)傳遞給lucene進行索引操作了。在索引操作時,lucene首先分析文本,將文本數(shù)據(jù)分割成詞匯單元,然后對它們執(zhí)行一些可選操作。文本分析包含了詞匯切割、大小寫轉(zhuǎn)換、移除停用詞等操作。分析過程的步驟很重要,這一步會產(chǎn)生大量的詞匯單元,隨后這些詞匯單元將被寫入索引文件中。

2.3向索引添加文檔

對文檔分析完畢之后,就可以將分析結(jié)果寫入索引文件了。lucene將輸入數(shù)據(jù)以一種倒排索引的數(shù)據(jù)結(jié)構(gòu)進行存儲。lucene索引都包含一個或者多個段(segment),每個段都是一個獨立的索引,它包含整個文檔索引的一個子集。

3.基本索引操作

3.1向索引添加文檔

添加文檔的方法有兩個:

  • addDocument(Document): 使用默認分析器添加文檔,該文檔分析器在創(chuàng)建IndexWriter對象時指定
  • addDocument(Document, Analyzer): 使用指定的分析器添加文檔
3.2刪除索引中的文檔

IndexWriter提供了各種方法來從索引中刪除文檔

  • deleteDocuments(Term): 負責刪除包含項的所有文檔
  • deleteDocuments(Term[]):負責刪除包含項數(shù)組任一元素的所有文檔
  • deleteDocuments(Query): 負責刪除匹配查詢語句的所有文檔
  • deleteDocuments(Query[]): 負責刪除匹配查詢語句數(shù)組任一元素的所有文檔
  • deleteAll(): 負責刪除索引中的所有文檔
3.3更新索引中的文檔

IndexWriter提供了兩個簡便的方法來更新索引中的文檔

  • updateDocument(Term, Document):首先刪除包含Term變量的所有文檔,然后使用writer的默認分析器添加新文檔
  • updateDocument(Term, Document, Analyzer):功能與上述一致,區(qū)別在于可以指定分析器添加文檔

4.域選項

4.1域索引選項
  • Index.ANALYZED:使用分析器將域值分解成詞匯單元,并建立索引
  • Index.NOT_ANALYZED: 不使用分析器分解閾值,并建立索引
  • Index.ANALYZED_NO_NORMS: 與Index.ANALYZED類似,但不存儲norms信息
  • Index.NOT_ANALYZED_NO_NORMS: 與Index.NOT_ANALYZED類似,但不存儲norm信息
  • Index.NO:不建立索引
4.2域存儲選項
  • Store.YES: 指定存儲閾值
  • Store.NO: 指定不存儲閾值
4.3域排序選項

如果需要按照某一域值對匹配的文檔集合進行排序,那么該閾值應該被正確的索引以及存儲。如果域是數(shù)值類型,在將它加入文檔和進行排序時,要用NumericField類來表示

4.4多值域

文檔的一個域可能有多個值,可以用document.add()多個域相同但域值不同的對象

5.對文檔和域進行加權(quán)操作

5.1文檔加權(quán)操作

調(diào)用加權(quán)操作的API只包含一個方法:documents.setBoost(float)

5.2域加權(quán)操作

使用field.setBoost(float)對域進行加權(quán)

5.3 加權(quán)基準

在索引期間,文檔中域的所有加權(quán)都被合并成一個單一的浮點數(shù)。除了域,文檔也有自己的加權(quán)值。這些權(quán)值被合并到一處,并被編碼(量化)成一個單一的字節(jié),作為域或文檔信息的一部分存儲起來。在搜索期間,被搜索域的norms都被加載到內(nèi)存,并被解碼還原為浮點數(shù),然后用于計算相關(guān)性評分(relevance score)。
雖然norms是在索引期間首次進行計算的,后續(xù)還是可以使用IndexReader的setNorm方法對它進行修改的。

6.索引數(shù)字、日期和時間

6.1索引數(shù)字

使用NumricField可以對數(shù)字進行索引。每個數(shù)值都用特里結(jié)構(gòu)(trie structure)進行索引,能實現(xiàn)高效的范圍搜索或者過濾功能。

6.2索引日期和時間

同樣使用NumricField索引時間??梢詫r間轉(zhuǎn)換成時間戳,在用NumricField

7.域截取

一些應用程序需要對尺寸未知的文檔進行索引。IndexWriter允許對域進行截取后再索引它們。傳入MaxFieldLength對象告知IndexWriter截取的長度。

8.近實時搜索

lucene通過調(diào)用IndexWriter中的對象方法實現(xiàn)近實時搜索:IndexReader getReader()。該方法能實時刷新緩沖區(qū)中新增或者刪除的文檔,然后創(chuàng)建新的包含這些文檔的只讀型IndexReader實例。

9.優(yōu)化索引

lucene中索引的優(yōu)化只是對段(segment)進行合并,這樣可以提升搜索效率。思考下搜索功能需要訪問各個段中的索引,減少了段的數(shù)量也就減少了掃描的次數(shù)。優(yōu)化索引只能提高搜索速度而不是索引速度。IndexWriter提供了4個優(yōu)化方法:

  • optimize()將索引壓縮至一個段,操作完成再返回
  • optimize(int maxNumSegments)也稱部分優(yōu)化,將索引壓縮為最多maxNumSegment個段
  • optimize(boolean doWait)跟optimize()類似,若doWait參數(shù)傳入false值,這樣的話調(diào)用會立即執(zhí)行,但合并工作是在后臺運行的
  • optimize(int maxNumSegments, boolean doWait)也是部分優(yōu)化
    注意索引優(yōu)化會消耗大量的cpu和i/o資源。

10.并發(fā)、線程安全及鎖機制

10.1線程安全和多虛擬機安全
  • 任意數(shù)量的只讀屬性的IndexReader類都可以同時打開一個索引。
  • 對于一個索引來說,一次只能打開一個Writer。lucene采用文件鎖來保證只有一個writer打開索引
  • 任意一個線程都可以共享同一個IndexReader類或者IndexWriter類
10.2索引鎖機制

鎖文件默認為write.lock,存在于索引目錄內(nèi)。

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

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

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