2011-10-25 75 views
0

當我的查詢中有特殊字符時,我得到了奇怪的結果。Solr Dismax處理程序 - 空格和特殊字符行爲

這裏是我的要求:

q=histoire-france&start=0&rows=10&sort=score+desc&defType=dismax&qf=any^1.0&mm=100% 

解析的查詢:

<str name="parsedquery_toString">+((any:histoir any:franc))()</str> 

因爲Solr的是做一個OR(應和)我已經得到了17000分的結果。

我沒有問題,當我使用的,而不是一個特殊字符一個空白:

q=histoire france&start=0&rows=10&sort=score+desc&defType=dismax&qf=any^1.0&mm=100% 

<str name="parsedquery_toString">+(((any:histoir) (any:franc))~2)()</str> 

2000結果此查詢。

這裏是我的schema.xml(相關部分):

<fieldType name="text" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="false"> 
     <analyzer type="index"> 
     <tokenizer class="solr.WhitespaceTokenizerFactory"/> 
     <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1" preserveOriginal="1"/> 
     <filter class="solr.LowerCaseFilterFactory"/> 
     <filter class="solr.CommonGramsFilterFactory" words="stopwords_french.txt" ignoreCase="true"/> 
     <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords_french.txt" enablePositionIncrements="true"/> 
     <filter class="solr.SnowballPorterFilterFactory" language="French" protected="protwords.txt"/> 
     <filter class="solr.RemoveDuplicatesTokenFilterFactory"/> 
     <filter class="solr.ASCIIFoldingFilterFactory"/> 
     </analyzer> 
     <analyzer type="query"> 
     <tokenizer class="solr.WhitespaceTokenizerFactory"/> 
     <!--<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>--> 
     <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1" preserveOriginal="0"/> 
     <filter class="solr.LowerCaseFilterFactory"/> 
     <filter class="solr.CommonGramsFilterFactory" words="stopwords_french.txt" ignoreCase="true"/> 
     <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords_french.txt" enablePositionIncrements="true"/> 
     <filter class="solr.SnowballPorterFilterFactory" language="French" protected="protwords.txt"/> 
     <filter class="solr.RemoveDuplicatesTokenFilterFactory"/> 
     <filter class="solr.ASCIIFoldingFilterFactory"/> 
     </analyzer> 
    </fieldType> 

我甚至有PatternTokenizerFactory試圖來標記的空格&特殊字符,但沒有改變...

我目前的解決方法是在向Solr發送查詢之前,用空格替換所有特殊字符,但這並不令人滿意。

編輯:即使有charFilter(PatternReplaceCharFilterFactory)用空格來代替特殊字符,這是行不通的......

通過Solr管理分析的第一行,用詳細輸出,查詢='史-法國」:

org.apache.solr.analysis.PatternReplaceCharFilterFactory {replacement= , pattern=([,;./\\'&-]), luceneMatchVersion=LUCENE_32} 
text histoire france 

在 ' - ' 所取代 '',然後通過WhitespaceTokenizerFactory記號化。不過,對於'histoire-france'和'histoire france',我仍然有不同的結果。

我錯過了什麼嗎?

+0

你重新索引數據?你需要重新索引數據才能看到任何變化 – Dorin

+0

是的我重新編制了數據 –

+0

你說你有你可以改變它爲 restart SOLR並分享每個查詢的結果數量。如果我猜這是真的,我會在稍後給你更詳細的解釋。 – Dorin

回答

1

這是一個錯誤:https://issues.apache.org/jira/browse/SOLR-3589

隨着edismax毫米設定爲100%,如果令牌之一被分析器鏈分割成兩個 令牌(即「火飛」 =>火飛) ,毫米 參數將被忽略,併產生OR查詢「fire or fly」 的等效項。對於不使用空格來分隔諸如中文或日文的詞的 的語言,這尤其是一個問題。

這是量變到質變,從WhiteSpaceTOckenizer到PatternTokenizer後固定在Solr的4.1(2013年1月22日)

1

使用WhitespaceTokenizerFactory,Solr會將您的查詢字符串拆分爲單詞。

但是,在標記後(Solr)使用solr.WordDelimiterFilterFactory將詞語(再次)分解爲詞彙。查看文檔並查看Wi-Fi示例。

這可能是一個原因,爲什麼histoire francehistoire-france被處理不同。

第二:不要忘記,DSIMAX(通常)將查詢項作爲「術語」處理,並且還將(另外)作爲解析的字符串處理。

要解決您的問題,您可以嘗試避免使用世界分隔符,並嘗試使用PatternTokenizerFactory(正如您之前嘗試過的,但現在沒有WordDelimiterFilterFactory)來處理「標記化」。

如果不工作,嘗試發佈analysys.jsp

0

的完整輸出啓用autoGeneratePhraseQueries爲真,這將產生的短語查詢。
因此,當搜索histoire-franc時,它將生成一個帶引號的查詢,該引號將只啓用具有兩個詞作爲短語匹配的文檔。

<str name="parsedquery">(+DisjunctionMaxQuery(((any:histoire any:franc))))/no_coord</str> 

實施例的工作配置 -

<fieldType name="text_test" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="true"> 
    <analyzer type="index"> 
    <tokenizer class="solr.WhitespaceTokenizerFactory"/> 
    <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/> 
    <filter class="solr.LowerCaseFilterFactory"/> 
    </analyzer> 
    <analyzer type="query"> 
    <tokenizer class="solr.WhitespaceTokenizerFactory"/> 
    <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/> 
    <filter class="solr.LowerCaseFilterFactory"/> 
    </analyzer> 
</fieldType> 

使用查詢污到例如指定廢油的數量qs=10在短語查詢中。

<str name="parsedquery">(+DisjunctionMaxQuery((any:"histoire france"~10)))/no_coord</str> 
+0

如果我添加autoGeneratePhraseQueries,則會爲「france-histoire」生成短語查詢,但不會生成「france histoire」。假設我有一個包含「法國曆史」的文件。然後短語「france-histoire」將不匹配... –

+0

使用查詢slop。更新了答案。 – Jayendra

3

你得到不同數量的結果搜索「史法國」和「史法」,因爲查詢分析器會在第二種情況下在第一種情況下短語查詢,和一個布爾查詢(獨立的兩個詞) 。

這不是明顯的行爲imho,但我相信很難滿足所有用例。

爲了使搜索處理「歷史學法國」作爲根本就是兩個詞,你可以添加「solr.PositionFilterFactory」來查詢分析器的結束,如:

<analyzer type="query"> 
    <tokenizer class="solr.StandardTokenizerFactory"/> 
    <filter class="solr.LowerCaseFilterFactory"/> 
    <filter class="solr.PositionFilterFactory" /> 
    </analyzer> 

然後搜索「史法國」和「歷史學結果法國「將是平等的。

請注意,位置過濾器可能不適合短語搜索(包括'historie'和'france')。考慮使用query slops參數qs> 0,以防止使用NGram過濾器修改了術語序列。