2012-04-17 47 views
10

我遇到了一個Lucene索引,其索引的單詞,包含「 - 」字符的問題。Lucene索引問題與「 - 」字符

它適用於包含「 - 」而不是所有的詞,我找不到原因,爲什麼它不工作。

我正在搜索的字段被分析幷包含帶有和不帶「 - 」字符的單詞版本。

我使用的分析:則把org.apache.lucene.analysis.standard.StandardAnalyzer

這裏一個例子:

如果我搜索「gsx- *」我得到了一個結果,索引字段包含 「SUZUKI GSX-R 1000 GSX-R1000 GSXR」

但如果我搜索「v- *」,我沒有結果。預期結果的索引字段包含: 「鈴木DL 1000 V-STROM DL1000V-STROMVSTROM V STROM」

如果我搜索「V-斯特羅姆」不帶「*」它的工作原理,但如果我只是搜索「 v-str「例如我沒有得到結果。 (應該有一個結果,因爲它是用於網上商店的實時搜索)

那麼,2個預期結果有什麼區別?爲什麼它適用於「gsx- 」,但不適用於「v-」?

+0

有趣的是,我使用Solr和驅動器V-斯特羅姆工作650 :) – 2012-04-17 07:38:23

+1

你有沒有去查看索引字段的內容,或者你只是希望它是這樣呢?如果不是用最大的Lucene索引工具不斷 - 盧克:http://code.google.com/p/luke/ – 2012-04-17 07:39:23

+0

是的,我顯示相同的領域,我在 – Zteve 2012-04-17 07:50:56

回答

12

我相信StandardAnalyzer會將連字符視爲空白。所以它會將您的查詢"gsx-*"變爲"gsx*""v-*",因爲它也消除了單字母標記。您在搜索結果中看到的字段內容是字段的存儲值,它完全獨立於爲該字段編制索引的術語。

所以你想要的是「v-strom」作爲一個整體是一個索引術語。 StandardAnalyzer不適合這種文本。也許有一個去與WhitespaceAnalyzerSimpleAnalyzer。如果仍然無法切割它,您也可以選擇將自己的分析儀放在一起,或者只需從這兩個想法開始,並進一步構成TokenFilters。一個很好的解釋是the Lucene Analysis package Javadoc.

給出BTW沒有必要在索引中,輸入所有變種像V-斯特羅姆,V-斯特羅姆等的想法是相同的分析儀正常化所有這些變體的索引中和解析查詢時都是相同的字符串。

+0

感謝您的幫助搜索,我知道顯示值是從搜索/索引字段中獨立出來的,但是對於測試,我顯示了我正在搜索的字段。我還使用盧克測試和分析問題。所以我確實需要的是,客戶可以輸入v-並獲得所有以v-開頭的結果。我需要改變什麼,它有效嗎?我只需要正確的語法,以便我可以更改客戶的查詢 – Zteve 2012-04-17 07:46:41

+0

我對Solr有點生疏,但是我會先爲您的模式添加一個額外的字段(例如product_name),您應該只使用小寫字段(field類型=小寫)。將此字段(OR)添加到您的搜索請求網址中,作爲更高權重的附加參數。 – 2012-04-17 09:31:22

+0

此字段中product_name的語法/值應該是什麼類型?與實際索引字段中的內容相同?也可以更改索引字段的值,因爲我可以將其更改爲例如「V-STROM v-strom vstrom v strom V STROM」,可以通過更改值來提供解決方案嗎?唯一確定的是,當客戶在搜索字段中輸入「v-str」或「v-」等時,應該能夠找到結果。 – Zteve 2012-04-17 09:53:31

3

ClassicAnalyzer將' - '作爲有用的非分隔符處理。正如我對ClassicAnalyzer的理解一樣,它處理' - '像3.1之前的StandardAnalyzer,因爲ClassicAnalyzer使用ClassicTokenizer,它將嵌入式' - '的數字作爲產品代碼處理,因此整個事物被標記爲一個術語。

當我在Regenstrief研究所時,我在升級Luke後注意到了這一點,因爲LOINC標準醫學術語(LOINC由RI發起)通過一個數字後跟一個' - '和一個校驗數字來標識,如'1-8 '或'2857-1'。我在Luke 3.5.0中使用StandardAnalyzer失敗了對'45963-6'等LOINC的搜索,但經典分析器成功(這是因爲我們使用2.9.2 Lucene.NET構建了索引)。

+0

我剛剛嘗試過,因爲Lucene 4.0.0 WhitespaceAnalyzer不會刪除連字符,但標準和經典的意志。 – 2012-07-25 02:07:27

1

ClassicAnalzer推薦用於索引包含產品代碼的文本,如「GSX-R1000」。它將認識到這是一個單一的術語,並沒有分割它的部分。但是,例如,「歐洲/柏林」將被ClassicAnalzer劃分爲「歐洲」和「柏林」。這意味着如果你有包含短語

Europe/Berlin GSX-R1000 

你可以搜索「歐洲」,「柏林」或「GSX-R1000」,由ClassicAnalyzer索引的文本。

但要小心您用於搜索的分析。我認爲搜索Lucene索引的最佳選擇是KeywordAnalyzer。隨着KeywordAnalyzer你也可以搜索特定字段的文檔中,你可以建立像複雜的查詢:

(processid:4711) (berlin) 

這個查詢將搜索文件與「柏林」,但也有場包含數字4711「的ProcessID」短語。

但是,如果你搜索索引的短語「歐洲/柏林」你會得到任何結果!這是因爲KeywordAnalyzer沒有改變您的搜索詞組,但ClassicAnalyzer將'Europe/Berlin'這個短語分成了兩個單獨的詞。這意味着您必須單獨搜索「歐洲」和「柏林」。

爲了解決這個矛盾,你可以轉換一個搜索詞,由用戶輸入,在適合你需要使用下面的代碼搜索查詢:

QueryParser parser = new QueryParser("content", new ClassicAnalyzer()); 
Query result = parser.parse(searchTerm); 
searchTerm = result.toString("content"); 

此代碼將轉化的檢索算法pharse

Europe/Berlin 

europe berlin 

這將導致預期的文件集。

注:這也將努力爲更復雜的情況。搜索條件

Europe/Berlin GSX-R1000 

將被翻譯成:

(europe berlin) GSX-R1000 

將搜索正確使用KeyWordAnalyzer結合所有詞組。