Solr同义词包含空格

时间:2016-06-14 20:19:41

标签: solr lucene

我有以下字段:

<fieldType name="brand" class="solr.TextField">
    <analyzer type="query">
        <tokenizer class="solr.KeywordTokenizerFactory"/>
        <filter class="solr.SynonymFilterFactory" synonyms="synonym-brand.txt" ignoreCase="false" expand="false"/>
    </analyzer>
</fieldType>

...

<field name="brand" type="brand" indexed="true" stored="false"/>

同义词文件有这样的内容:

foo => Adidas
bar => adidas originals

在搜索brand:foo时,搜索brand:Adidas会返回与brand:bar相同的结果,但不返回任何内容。

我的配置是否有问题,或者是multi-term synonym mapping so hard in Solr

2 个答案:

答案 0 :(得分:1)

Solr中的多项同义词绝对难以处理。在我看来,它最大的缺点之一。来自Solr Documentation

  

请记住,虽然SynonymFilter会很乐意使用   含有多个单词的同义词(即:&#34; 海饼干,海b,   seabiscuit &#34;)处理同义词的推荐方法   这,是在索引时扩展同义词。这是因为那里   是查询时可能出现的两个潜在问题:

     
      
  1. 在提供任何文本之前,Lucene QueryParser会在空格上进行标记   到分析器,所以如果一个人搜索海biscit的话   分析仪将被赋予&#34; sea &#34;和&#34; biscit &#34;单独地,和   不会知道他们是同义词。
  2.   
  3. 词组搜索(即:&#34; sea biscit &#34;)将导致QueryParser通过   整个字符串到   分析器,但如果SynonymFilter配置为扩展   同义词,然后当QueryParser获取结果的令牌列表时   从分析器返回,它将构建一个MultiPhraseQuery   没有达到预期的效果。这是因为机制有限   可用于分析器以指示两个术语占用相同的值   位置:没有办法表明一个&#34;短语&#34;占据了   与任期相同的立场。对于我们的例子,结果   MultiPhraseQuery将是&#34; (sea | sea | seabiscuit)(饼干|   biscit)&#34;这与&#34; seabiscuit&#34;的简单案例不符。   发生在文件中
  4.   

我处理此问题的方法是按照Solr文档和您链接的文章的建议,在索引时处理任何多字同义词。我创建了一个查询时间同义词文件来处理所有单个单词同义词集,以及一个单独的索引时间同义词文件,用于具有多个单词变体的集合。在您的示例中,xml看起来像这样

<fieldType name="brand" class="solr.TextField">
    <analyzer type="query">
        <tokenizer class="solr.KeywordTokenizerFactory"/>
        <filter class="solr.SynonymFilterFactory" synonyms="synonyms-query.txt" ignoreCase="false" expand="false"/>
    </analyzer>
    <analyzer type="index">
        <tokenizer class="solr.KeywordTokenizerFactory"/>
        <filter class="solr.SynonymFilterFactory" synonyms="synonyms-index.txt" ignoreCase="false" expand="true"/>
    </analyzer>
</fieldType>

synonyms-query.txt内容:

foo => Adidas

synonyms-index.txt内容:

adidas originals => bar

搜索brand:bar现在应该返回包含&#34; adidas原文&#34;的结果,但现在搜索brand:adidas不会返回结果。这是因为整个短语&#34; adidas原创&#34;已被&#34; bar&#34;取代在索引中。由于这可能不是您想要的,您可以更改synonyms-index.txt文件以使用等效的同义词而不是显式映射:

adidas originals, bar

使用此语法的任何&#34; adidas原创&#34;或&#34; bar&#34;将扩展到包含在索引中。如果您的品牌名称中没有一个实际包含&#34; bar&#34;那么这不应该是一个问题,但如果他们这样做,那么你可以使用this answer中提到的解决方法:

synonyms-query.txt内容:

foo => Adidas
bar => adidasoriginals
adidas originals => adidasoriginals

synonyms-index.txt内容:

adidas originals => adidasoriginals

此设置会从&#34; adidas原创&#34;中移除空格。在索引时和查询时。现在,该短语由索引中的单个标记表示,您可以在查询时使用显式映射,而不会遇到空白问题。

配置Solr同义词绝对是耐心等待的。那里有很多权力,但它相当令人困惑。祝你好运!

答案 1 :(得分:1)

我最后用下划线替换了空格(可能是任何其他在字段值中没有使用的字符):

<fieldType name="brand" class="solr.TextField">
    <analyzer type="index">
        <tokenizer class="solr.KeywordTokenizerFactory"/>
        <charFilter class="solr.PatternReplaceCharFilterFactory" pattern="(\s)" replacement="_"/>
    </analyzer>
    <analyzer type="query">
        <tokenizer class="solr.KeywordTokenizerFactory"/>
        <charFilter class="solr.PatternReplaceCharFilterFactory" pattern="(\s)" replacement="_"/>
        <filter class="solr.SynonymFilterFactory" synonyms="synonym-brand.txt" ignoreCase="false" expand="false"/>
    </analyzer>
</fieldType>