我正在尝试在solr中实现多字同义词,特别是类型
msc divina => divina
因此,如果用户输入“msc divina”,则solr应仅返回“divina”的结果。
schema.xml中的定义如下所示:
<fieldType name="text_de" class="solr.TextField" positionIncrementGap="100"
autoGeneratePhraseQueries="true">
<analyzer type="index">
<tokenizer class="solr.WhitespaceTokenizerFactory" />
<filter class="solr.SynonymFilterFactory"
synonyms="synonyms_de.txt"
ignoreCase="true"
expand="false" />
<filter class="solr.StopFilterFactory"
ignoreCase="true"
words="stopwords_de.txt"
enablePositionIncrements="true" />
<filter class="solr.WordDelimiterFilterFactory"
generateWordParts="1"
generateNumberParts="1"
catenateWords="1"
catenateNumbers="1"
catenateAll="0"
splitOnCaseChange="1" />
<filter class="solr.LowerCaseFilterFactory" />
<filter class="solr.KeywordMarkerFilterFactory"
protected="protwords_de.txt" />
<filter class="solr.SnowballPorterFilterFactory" language="German2" />
</analyzer>
<analyzer type="query">
<tokenizer class="solr.WhitespaceTokenizerFactory" />
<filter class="solr.StopFilterFactory"
ignoreCase="true"
words="stopwords_de.txt"
enablePositionIncrements="true" />
<filter class="solr.WordDelimiterFilterFactory"
generateWordParts="1"
generateNumberParts="1"
catenateWords="0"
catenateNumbers="0"
catenateAll="0"
splitOnCaseChange="1" />
<filter class="solr.LowerCaseFilterFactory" />
<filter class="solr.KeywordMarkerFilterFactory"
protected="protwords_de.txt" />
<filter class="solr.SnowballPorterFilterFactory" language="German2" />
</analyzer>
</fieldType>
它不起作用。如果我向查询分析器添加同义词过滤器,搜索“msc divina”将返回“msc and”divina“的每次命中。”
我该如何解决这个问题?
答案 0 :(得分:1)
从 Solr 6.4 开始,对于多字同义词,您需要使用solr.SynonymGraphFilterFactory
此过滤器映射单个或多个令牌同义词,生成一个完整的 正确的图形输出。此过滤器是同义词的替代品 过滤,为多标记同义词生成不正确的图形。
如果在索引编制期间使用此过滤器,则必须使用a 展平图形过滤器将标记拼写在彼此之上 同义词过滤器,因为索引器不能直接使用图形。至 在同义词替换时获得完全正确的位置查询 是多个令牌,你应该使用它来应用同义词 在查询时过滤。
索引时间分析器的示例:
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.SynonymGraphFilterFactory" synonyms="mysynonyms.txt"/>
<filter class="solr.FlattenGraphFilterFactory"/> <!-- required on index analyzers after graph filters -->
</analyzer>
由于现在令牌流是图形 - 将为文件的多字同义词提供适当的弧
fast → speedy
wi fi → wifi
wi fi network → hotspot
在这种情况下 - 多字词可以正常工作。
参考McCandless博客文章 - http://blog.mikemccandless.com/2012/04/lucenes-tokenstreams-are-actually.html
答案 1 :(得分:0)
来自Solr documentation:
请记住,虽然SynonymFilter会很乐意使用 包含多个单词的同义词(即:“sea biscuit,sea biscit, seabiscuit“)处理同义词的推荐方法 这,是在索引时扩展同义词。这是因为那里 是查询时可能出现的两个潜在问题:
在提供任何文本之前,Lucene QueryParser会在空格上进行标记 到分析器,所以如果一个人搜索海biscit的话 分析仪将分别给出“海”和“biscit”字样 不会知道他们是同义词。词组搜索(即:“海 biscit“)将导致QueryParser将整个字符串传递给 分析器,但如果SynonymFilter配置为扩展 同义词,然后当QueryParser获取结果的令牌列表时 从分析器返回,它将构建一个MultiPhraseQuery 没有达到预期的效果。这是因为机制有限 可用于分析器以指示两个术语占用相同的值 位置:没有办法表明“短语”占据了 与任期相同的立场。对于我们的例子,结果 MultiPhraseQuery将是“(海|海| seabiscuit)(饼干| biscit)“这与”seabiscuit“的简单案例不符 在文档中出现
在这里,他们描述了一个问题:除非您使用sea biscit
,否则无法搜索seabiscuit
并获得与已编入索引expand=true
的匹配,但他们也会解释查询中会发生什么时间与多字查询,这是你的情况。
msc divina -> msc | divina - phrase query
将匹配msc和divina文档。如果您可以在查询时指定搜索"msc divina"
它将起作用。
否则,您需要在查询时使用多字识别标记器,或者您可以展开FieldQParser
插件来为您执行此操作。您可以找到更多here。
答案 2 :(得分:0)
以下是您可以在互联网上找到的解决方案:https://dzone.com/articles/solution-multi-term-synonyms
除此之外,我对此问题的解决方案是特定于域的。在我的情况下,我确定我的查询长度(即少于200或只有5-10个单词)。
我在同义词条目中用下划线替换了空格。这是我的同义词条目之一:
"like_to":["love_to","loves_to","need_to","needs_to"]
使用KeywordTokenizerFactory发送完整的过滤查询
<tokenizer class="solr.KeywordTokenizerFactory"/>
使用ShingleFilterFactory索引/查询minShingleSize
和mazShingleSize
之间所有可能的子短语。
<filter class="solr.ShingleFilterFactory" minShingleSize="2" outputUnigrams="true" maxShingleSize="3"/>
然后使用PatternReplaceCharFilterFactory将空格替换为下划线(_
)
<charFilter class="solr.PatternReplaceCharFilterFactory" pattern="\\s+" replacement="_"/>
使用您的同义词过滤器工厂。
查询:I love to travel
代币:I love, I love to, love to, love to travel, to travel, tavel
替换为_
:I_love, I_love_to, love_to, love_to_travel, to_travel, tavel
同义词过滤器将这些转换为:I_love, I_love_to, like_to, love_to_travel, to_travel, tavel
因此,它最终会将love to
词组更改为like to
。
希望这个技巧有所帮助,尽管它涉及昂贵的操作。