solr中的多字同义词

时间:2013-11-12 11:09:04

标签: solr synonym

我正在尝试在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“的每次命中。”

我该如何解决这个问题?

3 个答案:

答案 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

enter image description here

在这种情况下 - 多字词可以正常工作。

参考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个单词)。

  1. 我在同义词条目中用下划线替换了空格。这是我的同义词条目之一:

    "like_to":["love_to","loves_to","need_to","needs_to"]
    
  2. 使用KeywordTokenizerFactory发送完整的过滤查询

    <tokenizer class="solr.KeywordTokenizerFactory"/>
    
  3. 使用ShingleFilterFactory索引/查询minShingleSizemazShingleSize之间所有可能的子短语。

    <filter class="solr.ShingleFilterFactory" minShingleSize="2" outputUnigrams="true" maxShingleSize="3"/>
    
  4. 然后使用PatternReplaceCharFilterFactory将空格替换为下划线(_

    <charFilter class="solr.PatternReplaceCharFilterFactory" pattern="\\s+" replacement="_"/>
    
  5. 使用您的同义词过滤器工厂。

  6. 实施例

    查询: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

    希望这个技巧有所帮助,尽管它涉及昂贵的操作。