我有以下字段:
<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?
答案 0 :(得分:1)
Solr中的多项同义词绝对难以处理。在我看来,它最大的缺点之一。来自Solr Documentation:
请记住,虽然SynonymFilter会很乐意使用 含有多个单词的同义词(即:&#34; 海饼干,海b, seabiscuit &#34;)处理同义词的推荐方法 这,是在索引时扩展同义词。这是因为那里 是查询时可能出现的两个潜在问题:
- 在提供任何文本之前,Lucene QueryParser会在空格上进行标记 到分析器,所以如果一个人搜索海biscit的话 分析仪将被赋予&#34; sea &#34;和&#34; biscit &#34;单独地,和 不会知道他们是同义词。
- 词组搜索(即:&#34; sea biscit &#34;)将导致QueryParser通过 整个字符串到 分析器,但如果SynonymFilter配置为扩展 同义词,然后当QueryParser获取结果的令牌列表时 从分析器返回,它将构建一个MultiPhraseQuery 没有达到预期的效果。这是因为机制有限 可用于分析器以指示两个术语占用相同的值 位置:没有办法表明一个&#34;短语&#34;占据了 与任期相同的立场。对于我们的例子,结果 MultiPhraseQuery将是&#34; (sea | sea | seabiscuit)(饼干| biscit)强>&#34;这与&#34; seabiscuit&#34;的简单案例不符。 发生在文件中
醇>
我处理此问题的方法是按照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>