【问题标题】:Solr / Lucene token n-gram: leading and trailing stopwords removal onlySolr / Lucene 令牌 n-gram:仅删除前导和尾随停用词
【发布时间】:2020-11-04 22:07:55
【问题描述】:

有没有办法从标记 n-gram 中只删除前导和尾随停用词?

目前我有以下组合可以删除任何包含停用词的 n-gram:

<analyzer type="index">
            <tokenizer class="solr.StandardTokenizerFactory" />
            <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
            <filter class="solr.LowerCaseFilterFactory" />
            <filter class="solr.ShingleFilterFactory" minShingleSize="2" maxShingleSize="3"
                    outputUnigrams="true" outputUnigramsIfNoShingles="false" tokenSeparator=" "/>
            <filter class="solr.PatternReplaceFilterFactory" pattern=".*_.*" replacement=""/>
</analyzer>

例如,如果我的文档包含这些 ngram:

“伦敦塔”、“伦敦塔”、“和伦敦”、“伦敦”、

以“of, in”作为停用词,shingle 过滤器将产生:

塔_伦敦,塔_伦敦,_伦敦,伦敦

(请注意,第二个“tower _ london”与第一个不同,但是这部分信息丢失了)

然后模式过滤器将删除前 3 个 n-gram。

我真正想做的是保留“伦敦塔”、“伦敦塔”、“伦敦”、“伦敦”。

这可能吗?

非常感谢!

【问题讨论】:

  • 如果您担心信息丢失,为什么要删除停用词?在我看来,常见的停用词在句子开头或结尾的影响并不比在中间的影响小。毕竟“在路上”和“在路上”也有明显不同的含义。为什么不直接从分析仪中完全删除 StopFilterFactory

标签: solr lucene


【解决方案1】:

当我尝试构建一个自动完成功能时,我遇到了同样的问题,该功能将从 shingled 标记中获取建议(尾随停用词看起来很有趣)。

我最终开发了一个 TokenFilter 来做到这一点:https://github.com/spyk/shingle-stop-filter。如果您不介意向 Solr 添加额外的 jar,可以查看它。此外,它目前仅适用于尾随停用词,尽管它也可以针对前导停用词进行调整。

【讨论】:

    【解决方案2】:

    您可能想要查看 CommonGrams 分析器而不是 Shingle 分析器。我不认为他们是完美的匹配(他们只做二元组),但你可能会发现他们在搜索你想要的东西时表现得更接近。

    另一种选择是将PatternReplace过滤器工厂粘贴在Shingle之后的链中,并在n-gram的开头捕获那些常用词并将它们替换掉。之后您可能还需要RemoveDuplicate 过滤器以仅保留一个版本 - 现在相同 - 令牌。

    【讨论】:

      【解决方案3】:

      这可能有点晚了,但它对我有用,我认为这对可能面临同样问题的其他人来说会很有趣。

      您在 fieldType 中放置过滤器的顺序会影响结果。 在 StopFilterFactory 之前使用 ShingleFilterFactory 时,我得到了您所期望的结果。

          <analyzer type="index">
              <charFilter class="solr.HTMLStripCharFilterFactory"/>
              <tokenizer class="solr.StandardTokenizerFactory"/>
              <filter class="solr.LowerCaseFilterFactory"/>
              <filter class="solr.PatternReplaceFilterFactory" pattern="(^[^a-zA-Z0-9á-úÁ-Ú]*|[^a-zA-Z0-9á-úÁ-Ú]*$)" replacement=""/>
              <filter class="solr.ShingleFilterFactory" outputUnigrams="true" minShingleSize="2" maxShingleSize="6"
              tokenSeparator=" "/> 
              <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords_pt.txt" />
          </analyzer>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-08-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多