【问题标题】:Solr: combining EdgeNGramFilterFactory and NGramFilterFactorySolr:结合 EdgeNGramFilterFactory 和 NGramFilterFactory
【发布时间】:2011-08-30 05:42:34
【问题描述】:

我遇到需要同时使用 EdgeNGramFilterFactory 和 NGramFilterFactory 的情况。

我正在使用 NGramFilterFactory 执行“包含”样式搜索,最小字符数为 2。我还想搜索第一个字母,例如带有前端 EdgeNGramFilterFactory 的“startswith”。

我不想将 NGramFilterFactory 降低到最少 1 个字符,因为我不想索引所有字符。

非常感谢您的帮助

干杯

【问题讨论】:

    标签: java lucene solr


    【解决方案1】:

    您不必在同一个领域完成所有这些工作。我会为每种处理使用不同的自定义类型创建不同的字段,以便您可以单独应用逻辑。

    如下:

    • text 包含原始令牌,经过最少处理;
    • text_ngram 将 NGramFilter 用于您的最少两个字符的标记
    • text_first_letter 使用 EdgeNGram 作为您的单字符首字母标记

    如果您正在以这种方式处理所有 text 字段,那么您也许可以使用 copyField 来填充字段。否则,您可以指示 Solr 客户端为三种不同的字段类型发送相同的字段值。

    搜索时,使用qf 参数将所有这些都包含在搜索中。

    <fieldType name="text" class="solr.TextField" positionIncrementGap="100">
      <analyzer>
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.StandardFilterFactory"/>
        <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>
    </fieldType>
    
    <fieldType name="text_ngram" class="solr.TextField" positionIncrementGap="100">
      <analyzer>
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.StandardFilterFactory"/>
        <filter class="solr.LowerCaseFilterFactory"/>
        <filter class="solr.NGramFilterFactory" minGramSize="2" maxGramSize="15" side="front"/>
      </analyzer>
    </fieldType>
    
    <fieldType name="text_first_letter" class="solr.TextField" positionIncrementGap="100">
      <analyzer>
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.StandardFilterFactory"/>
        <filter class="solr.LowerCaseFilterFactory"/>
        <filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="1" side="front"/>
      </analyzer>
    </fieldType>
    

    设置 fielddynamicField 定义由您决定。或者,如果您有更多问题,请告诉我,我可以进行编辑并进行澄清。

    【讨论】:

    • 感谢您的回答,虽然我们希望在同一个领域中使用它,因为在很多情况下我们都需要它,但这会奏效!
    • @Nick Nadrozny,您能否告诉我如何执行此操作:“否则,您可以指示您的 Solr 客户端为三种不同的字段类型发送相同的字段值。”和“搜索时,使用 qf 参数将所有这些都包含在搜索中。”?谢谢。
    【解决方案2】:

    首先应用最小值 = 1 和最大值 = 1000 的 EdgeNgramFilter(我们希望包含整个原始标记)。示例:

    你好 => 'h', 'he', 'hel', 'hell', '你好'

    其次使用 min = 2 的 NGramFilter。(为简单起见,我将在示例中使用 2 作为最大值)

    'h', 'he', 'hel', 'hell', 'hello' => 'h', 'he', 'he', 'el', 'he', 'el', 'll ', '他', 'el', '会', 'lo'

    现在您将拥有几个相同的令牌,因为您已对 EdgeNGramFilter 中的所有“部分”令牌应用了 NGramFilter,但只需应用 RemoveDuplicatesTokensFilter 即可删除这些令牌。

    'h', 'he', 'he', 'el', 'he', 'el', 'll', 'he', 'el', 'll', 'lo' => 'h ', '他', 'el', '会', 'lo'

    现在您的字段将支持单字符“startsWith”查询和多字符“包含”查询。

    【讨论】:

    • 这不起作用,因为 contains NGram 会删除由startswith EdgeNgram 过滤器生成的任何单个字符
    猜你喜欢
    • 2015-07-29
    • 2021-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多