2011-10-25 39 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过滤器修改了术语序列。