0 Lucene的分析過程 jopen 12年前發布 | 71K 次閱讀 Lucene 搜索引擎 Lucene的分析過程 回顧倒排索引的構建 收集待建索引的原文檔(Document) 將原文檔傳給詞條化工具(Tokenizer)進行文本詞條化 將第二步得到的詞條(Token)傳給語言分析工具(Linguistic modules)進行語言學預處理,得到詞項(Term) 將得到的詞項(Term)傳給索引組件(Indexer),建立倒排索引 注:詳細文檔->倒排索引的理論過程見詞項詞典及倒排記錄表 分析操作的使用場景 1.如上,倒排索引的構建階段 2.針對自由文本的查詢階段 QueryParser parser = new QueryParser(Version.LUCENE_36, field, analyzer); Query query = parser.parse(queryString); lucene的Analyzer接收表達式queryString中連續的獨立的文本片段,但不會接收整個表達式。 例如:對查詢語句"president obama" + harvard + professor,QueryParser會3次調用分析器,首先是處理文本“president obama”,然后是文本“harvard”,最后處理“professor”。 3.搜索結果中高亮顯示被搜索內容時(即結果摘要-Snippets的生成),也可能會用到分析操作 剖析lucene分析器 抽象類Analyzer Analyzer類是一個抽象類,是所有分析器的基類。 其主要包含兩個接口,用于生成TokenStream(所謂TokenStream,后面我們會講到,是一個由分詞后的Token 結果組成的流,能夠不斷的得到下一個分成的Token。)。 接口: 1.TokenStream tokenStream(String fieldName, Reader reader) 2.TokenStream reusableTokenStream(String fieldName, Reader reader) 為了提高性能,使得在同一個線程中無需再生成新的TokenStream 對象,老的可以被重用,所以有reusableTokenStream 一說。 Analyzer 中有CloseableThreadLocal tokenStreams = newCloseableThreadLocal(); 成員變量, 保存當前線程原來創建過的TokenStream , 可用函數setPreviousTokenStream 設定,用函數getPreviousTokenStream 得到。在reusableTokenStream 函數中,往往用getPreviousTokenStream 得到老的TokenStream 對象,然后將TokenStream 對象reset 一下,從而可以重新開始得到Token 流。   抽象類ReusableAnalyzerBase ReusableAnalyzerBase extendsAnalyzer,顧名思義主要為tokenStream的重用。 其包含一個接口,用于生成TokenStreamComponents。 接口: TokenStreamComponents createComponents(String fieldName,Reader reader);   reusableTokenStream的實現代碼分析: public final TokenStream reusableTokenStream(final String fieldName, final Reader reader) throws IOException { // 得到上一次使用的TokenStream TokenStreamComponents streamChain = (TokenStreamComponents)getPreviousTokenStream(); final Reader r = initReader(reader); //如果沒有PreviousTokenStream則生成新的, 并且用setPreviousTokenStream放入成員變量,使得下一個可用。 //如果上一次生成過TokenStream,則reset。reset失敗則生成新的。 if (streamChain == null || !streamChain.reset(r)) { streamChain = createComponents(fieldName, r); setPreviousTokenStream(streamChain); } return streamChain.getTokenStream(); } 內部static類TokenStreamComponents 簡單封裝輸入Tokenizer和輸出TokenStream。   最簡單的一個Analyzer:SimpleAnalyzer SimpleAnalyzer extendsReusableAnalyzerBase,實現createComponents方法。TokenStream的處理是將字符串最小化,生成按照空格分隔的Token流 protected TokenStreamComponents createComponents( final String fieldName, final Reader reader) { return new TokenStreamComponents(new LowerCaseTokenizer(matchVersion , reader)); } 抽象類TokenStream TokenStream 主要包含以下幾個方法: 1. boolean incrementToken()用于得到下一個Token。IndexWriter調用此方法推動Token流到下一個Token。實現類必須實現此方法并更新Attribute信息到下一個Token。 2. public void reset() 重設Token流到開始,使得此TokenStrean 可以重新開始返回各個分詞。   和原來的TokenStream返回一個Token 對象不同,Lucene 3.0 開始,TokenStream已經不返回Token對象了,那么如何保存下一個Token 的信息呢? 在Lucene 3.0 中,TokenStream 是繼承于AttributeSource,其包含Map,保存從class 到對象的映射,從而可以保存不同類型的對象的值。在TokenStream 中,經常用到的對象是CharTermAttributeImpl,用來保存Token 字符串;PositionIncrementAttributeImpl 用來保存位置信息;OffsetAttributeImpl 用來保存偏移量信息。所以當生成TokenStream 的時候, 往往調用CharTermAttribute tokenAtt = addAttribute(CharTermAttribute.class)將CharTermAttributeImpl添加到Map 中,并保存一個成員變量。在incrementToken() 中, 將下一個Token 的信息寫入當前的tokenAtt , 然后使用CharTermAttributeImpl.buffer()得到Token 的字符串。 注:Lucene 3.1開始廢棄了TermAttribute和TermAttributeImpl,用CharTermAttribute和CharTermAttributeImpl代替。   Token attributes 如上述,Token的信息真正存在于各個AttributeImpl中,lucene內建的所有Attribute接口都在org.apache.lucene.analysis.tokenattributes包中。   Token attributes API的使用 1. 調用addAttribute(繼承于AttributeSource)方法,返回一個對應屬性接口的實現類,以獲得需要的屬性。 2. 遞歸TokenStream incrementToken()方法,遍歷Token流。當incrementToken返回true時,其中Token的屬性信息會將內部狀態修改為下個詞匯單元。 3. lucene內建Attribute接口都是可讀寫的,TokenStream 在遍歷Token流時,會調用Attribute接口的set方法,修改屬性信息。   lucene內建常用Attribute接口 1. CharTermAttribute      保存Token對應的term文本,Lucene 3.1開始用CharTermAttribute代替TermAttribute 2. FlagsAttribute             自定義標志位 3. OffsetAttribute            startOffset是指Term的起始字符在原始文本中的位置,endOffset則表示Term文本終止字符的下一個位置。偏移量常用于搜索結果中高亮Snippets的生成 4. PayloadAttribute          保存有效負載 5. TypeAttribute              保存Token類型,默認為"word",實際中可根據Term的詞性來做自定義操作 6. PositionIncrementAttribute  保存相對于前一個Term的位置信息,默認值設為1,表示所有的Term都是連續的,在位置上是一個接一個的。如果位置增量大于1,則表示Term 之間有空隙,可以用這個空隙來表示被刪除的Term項(如停用詞)。位置增量為0,則表示該Term項與前一個Term項在相同的位置上,0增量常用來表 示詞項之間是同義詞。位置增量因子會直接影響短語查詢和跨度查詢,因為這些查詢需要知道各個Term項之間的距離。 注:并不是所有的Attribute信息都會保存在索引中,很多Attribute信息只在分析過程使用,Term進索引后部分Attribute信息即丟棄。(如TypeAttribute、FlagsAttribute在索引階段都會被丟棄)   Lucene Token流 揭秘 lucene Token流的生成,主要依賴TokenStream 的兩個子類Tokenizer和TokenFilter Tokenizer類的主要作用:接收Read對象,讀取字符串進行分詞并創建Term項。 TokenFilter類使用裝飾者模式(lucene in action中作者寫的是組合模式,本人竊以為應該是裝飾者模式),封裝另一個TokenStream類,主要負責處理輸入的Token項,然后通過新 增、刪除或修改Attribute的方式來修改Term流。   如上圖,當Analyzer從它的tokenStream方法或者reusableTokenStream方法返回tokenStream對象后, 它就開始用一個Tokenizer對象創建初始Term序列,然后再鏈接任意數量的TokenFilter來修改這些Token流。這被稱為分析器鏈 (analyzer chain)。   一個簡單的Analyzer:StopAnalyzer protected TokenStreamComponents createComponents(String fieldName, Reader reader) { //LowerCaseTokenizer接收Reader,根據Character.isLetter(char)來進行分詞,并轉換為字符小寫 final Tokenizer source = new LowerCaseTokenizer(matchVersion , reader); //只有一個分析器鏈StopFilter,來去除停用詞 return new TokenStreamComponents(source, new StopFilter(matchVersion , source, stopwords)); } StopAnalyzer測試 String text = "The quick brown fox jumped over the lazy dog"; System. out.println("Analyzing \"" + text + "\""); Analyzer analyzer = new StopAnalyzer(Version.LUCENE_36); String name = analyzer.getClass().getSimpleName(); System. out.println("" + name + ":"); System. out.print("" );AnalyzerUtils. displayTokens(analyzer, text); System. out.println("\n" ); 結果輸出 Analyzing "The quick brown fox jumped over the lazy dog"   StopAnalyzer:     [quick] [brown] [fox] [jumped] [over] [lazy] [dog]     作者: God bless you 出處: http://www.cnblogs.com/god_bless_you/ 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享! 本文地址:http://www.baiduhome.net/lib/view/open1348033848724.html Lucene 搜索引擎 相關經驗 Lucene的分析過程 Elasticsearch 分片交互過程分析 BroadcastReceiver 的工作過程分析 mapreduce源碼分析作業分配過程 MySQL服務器連接過程分析 相關資訊 Lucene 的 .NET 版本,Lucene.Net 3.0.3 發布 Lucene的.NET版本 Lucene.net 2.9.4 發布 Lucene 網站改版 Lucene 和 Solr 4.8 發布 Apache Lucene 4.0 Beta 發布 相關文檔 我的Android的root過程分析 aix疑難問題分析過程 Namenode 啟動過程分析 軟件需求分析的任務和過程 Lucene 課程 Lucene 課程 時間系列分析及應用R語言(答案) 目錄