最近一直在研究solr的源碼,主要是標準分詞源碼分析:
solr底層是使用的是Lucene,標準分詞的問題其實 也是lucene的底層的問題。
閑話不多說,最近在項目中遇到各種與公司業務相悖的問題,開始使用solr6.3配置一個單機的solr,分詞用的是目前國內比較流行的ik分詞器,分詞速度和索引速度,也比較可以,但是在搜索的時候遇到了很多問題,也是分詞造成的問題,其中包括:搜索漏詞、漏新聞、關鍵字新增的問題,最後考慮到公司沒有目前詞庫量沒有那麽大,而且公司搜索那塊業務,是不斷更新新詞,所以決定采用一元分詞,(標準分詞),用標準分詞的確滿足了公司的搜索業務,但是不用考慮新增關鍵字,搜索中詞量不足造成的影響。
但是在搜索時 卻還是有一些問題,比如用標準分詞,搜索“國美” 結果會匹配出 “國,美”這類信息,搜索會出現誤差,一些特殊符號,也不能搜索分詞 如“C++、C#”,因此我下載solr的源碼 ,準備對分詞這塊源碼進行一些調整,適合於我們業務 。
solr源碼包 本身不是 一個Java項目,是一個 基於ant的文件,需要下載 ant工具,這個 可以百度自己安裝,安裝成功後,還需要一個ivy插件,具體操作百度;簡單的一些配置。然後打成源碼包,導入eclipse中,就可以隨心所欲的研究源碼了。
開始 分析源碼》》》
solr的標準分詞源碼入口都是一個 StandardTokenizerFactory 的類;solr在建立索引和搜索的時候需要拆分它們、並做一些相應的處理(比如英文要去掉介詞、轉成小寫、單詞原形化等,中文要恰當地要分詞)。這些工作,一般由Analyzers、Tokenizers、和Filter來實現。這三個都是在配置在fieldType中。
ananlyzer:告訴solr在建立索引和搜索的時候,如何處理text類型的內容,比如要不要去掉“a”、去掉介詞、去掉復數,要不要全部變成小寫等等。。。它在managed-schema文件中配置,可以直接指定一個類給它;也可以由tokenizer和filter的組合來實現:
- type:可選參數,index或query,表名這個配置是在建立索引還是在搜索的時候使用
- tokenizer:分詞器,比如:StandardTokenizerFactory
- filter:過濾器,比如:LowerCaseFilterFactory,小寫轉換
- Analyzer負責把文本field轉成token流,然後自己處理、或調用Tokenzier和Filter進一步處理,Tokenizer和Filter是同等級和順序執行的關系,一個處理完後交給下一個處理代碼如下:
- 再通過filter過濾大小寫、同義詞、和數字等操作。
上面代碼是,停用詞相關的操作
Tokenizer和Filter的區別:
- Tokenizer:接收text(通過從solr那裏獲得一個reader來讀取文本),拆分成tokens,輸出token stream
- Filter:接收token stream,對每個token進行處理(比如:替換、丟棄、不理),輸出token stream
因此,在配置文件中,Tokenizer放在第一位,Filter放在第二位直到最後一位。
- token:標記、記號,solr中被用來索引或搜索的最小元素,比如英文單詞的原形、中文的詞語。tokenize:分詞,tokenizer:分詞器。
- stem:詞幹,EnglishPorterFilterFactory負責把單詞還原成詞幹,比如:hugs, hugging, hugged -> hug。
- 最後重點:修改分詞器讓分詞適合我們自己的業務
package org.apache.lucene.analysis.standard.StandardTokenizerImpl.java Java文件753行的位置添加判斷如果輸入的字符(zzInput)為- ,就將zzNext (The transition table of the DFA)值設置為2,”-“在(ASCII 表)十進制的值為:45 詳情參考下圖
if(zzInput==45) {
zzNext = 2}
solr源碼位置在
這樣就能讓solr分詞,分出特殊字符
分詞結果如下:
Tags: 特殊符號 java項目 隨心所欲 百度 關鍵字
文章來源: