【问题标题】:Multi word synonyms in solrsolr 中的多词同义词
【发布时间】:2013-11-12 11:09:03
【问题描述】:

我正在尝试在 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 和“divina”的每个匹配项。

我该如何解决这个问题?

【问题讨论】:

标签: solr synonym


【解决方案1】:

Solr 6.4 开始,您需要使用 solr.SynonymGraphFilterFactory 的多词同义词

此过滤器映射单个或多个标记的同义词,生成完整的 正确的图形输出。此过滤器是同义词的替代品 过滤器,它会为多标记同义词生成不正确的图表。

如果您在索引期间使用此过滤器,则必须在其后面加上 展平图形过滤器以将令牌彼此压扁,例如 同义词过滤器,因为索引器不能直接使用图。到 当您的同义词替换时获得完全正确的位置查询 是多个标记,您应该使用这个来应用同义词 在查询时过滤。

索引时间分析器示例:

<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

【讨论】:

    【解决方案2】:

    来自 Solr documentation:

    请记住,虽然 SynonymFilter 很乐意与 包含多个单词的同义词(即:“sea biscuit, sea biscit, seabiscuit") 处理同义词的推荐方法,例如 this,就是在索引的时候展开同义词。这是因为有 是查询时可能出现的两个潜在问题:

    Lucene QueryParser 在给出任何文本之前对空白进行标记 到分析器,所以如果一个人搜索单词 sea biscit 分析器将分别给出“sea”和“biscit”这两个词,并且 不会知道它们匹配同义词。词组搜索(即:“海 biscit") 将导致 QueryParser 将整个字符串传递给 分析器,但如果 SynonymFilter 配置为扩展 同义词,然后当 QueryParser 获得令牌的结果列表时 从分析器返回,它将构造一个 MultiPhraseQuery,它将 没有达到预期的效果。这是因为有限的机制 可供分析器指示两个术语占用相同 位置:没有办法表明一个“短语”占据了 与术语相同的位置。对于我们的示例,结果 MultiPhraseQuery 将是“(sea | sea | seabiscuit) (biscuit | biscit)”,这与“seabiscuit”的简单情况不匹配 发生在文档中

    在这里,他们描述了一个问题:您无法搜索 sea biscit 并在索引的 seabiscuit 上找到匹配项,除非您使用 expand=true,但他们还解释了在查询时使用多字查询会发生什么这是你的情况。

    msc divina -> msc | divina - phrase query
    

    这将匹配 msc 和 divina 文档。如果您可以在查询时指定搜索"msc divina",它将起作用。

    否则,您需要在查询时使用多词识别标记器,或者您可以扩展 FieldQParser 插件来为您执行此操作。你可以找到更多here

    【讨论】:

    • 感谢您的回答。这就是我感到困惑的地方:“索引时扩展同义词”,这与您上面所说的一致。但如果 expand=true(在索引分析器中),将同义词扩展为“msc”、“divina”和“msc divina”,因为我不希望这样。我希望“msc divina”成为“divina”的同义词。另一个困惑是我是否应该在查询分析器上也有一个同义词过滤器,扩展值应该是什么?
    • 看起来有一个为issues.apache.org/jira/browse/SOLR-5379 提交的补丁可以解决同样的问题。另请查看相关的 jira 问题以获取更多信息。祝你好运
    【解决方案3】:

    这是您可以在互联网上找到的解决方案: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. 使用同义词过滤器工厂。

    示例

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-29
      • 1970-01-01
      • 1970-01-01
      • 2012-01-26
      • 1970-01-01
      • 2023-04-04
      • 2023-03-27
      相关资源
      最近更新 更多