【问题标题】:Tokenize result of a NGramFilterFactory in Solr (query analyzer)在 Solr(查询分析器)中标记 NGramFilterFactory 的结果
【发布时间】:2012-02-10 09:51:48
【问题描述】:

我正在使用 NGramFilterFactory 进行索引和查询。

因此,如果我正在搜索“溢出”,它会创建如下查询:

mySearchField:"ov ve ... erflow overflo verflow overflow"

但是如果我拼错了“overflow”,即“owerflow”,则没有匹配项,因为查询周围的引号:

mySearchField:"ow we ... erflow owerflo werflow owerflow"

是否可以标记 NGramFilteFactory 的结果,它会创建如下查询:

mySearchField:"ow"
mySearchField:"we"
mySearchField:"erflow"
mySearchField:"owerflo"
mySearchField:"werflow"
mySearchField:"owerflow"

在这种情况下,solr 也会找到结果,因为存在令牌“erflow”。

【问题讨论】:

    标签: filter solr full-text-search tokenize


    【解决方案1】:

    您不需要像您写的那样标记您的查询。检查您的schema.xml 中是否在索引时间和查询时间都应用了NGramFilterFactory。 然后,您使用的查询解析器会有所作为。使用LuceneQParser,你会得到你正在寻找的结果,但不是DisMaxeDisMax

    我用eDisMaxdebugQuery=on检查了查询mySearchField:owerflow

    <str name="querystring">text:owerflow</str>
    <str name="parsedquery">
    +((text:o text:w text:e text:r text:f text:l text:o text:w text:ow text:we text:er text:rf text:fl text:lo text:ow text:owe text:wer text:erf text:rfl text:flo text:low text:ower text:werf text:erfl text:rflo text:flow text:owerf text:werfl text:erflo text:rflow text:owerfl text:werflo text:erflow text:owerflo text:werflow text:owerflow)~36)
    </str>
    

    如果您查看生成的查询的末尾,您会看到~36,其中 36 是您的查询生成的 n-gram 数。由于~36,您不会得到任何结果,但您可以通过mm 参数更改它,这是应该匹配的最小值。

    如果您将查询更改为 mySearchField:owerflow&amp;mm=1 或低于 25 的值,您将获得您正在寻找的结果。

    此答案与您的答案之间的区别在于,对于 EdgeNGramFilterFactory,像 mySearchField:werflow 这样的中缀查询不会返回任何结果,而对于 NGramFilterFactory 则有。

    无论如何,如果您使用NGramFilterFactory 进行拼写更正,我强烈建议您也查看一下SpellCheckComponent,它正是为此目的而制作的。

    【讨论】:

    • 感谢您的回答。 SpellCheckComponent 不适合我的具体情况,因为我需要拼写错误单词的搜索结果,而不是正确拼写的建议。但我找到了另一种解决方案(见我的回答)。
    • @MaxSchmidt 我有机会深入了解您的问题并使用NGramFilterFactory 找到了解决方案,请查看我更新的答案。无论如何,您当然可以使用SpellCheckComponent 对拼写错误的单词进行拼写更正。
    • 这很奇怪。使用 eDisMax 和 debugQuery=on 且不使用 autoGeneratePhraseQueries="false" 我得到: text:overflow +DisjunctionMaxQuery((text:"o v e r f l o w ov er射频流")) ()
    • 奇怪!哪个solr版本?你确定eDisMax 不是DisMax
    • 确切查询字符串:localhost:8983/solr/… 我使用的是 solr/lucene 3.5
    【解决方案2】:

    好的,我找到了解决问题的快速简便的方法。

    fieldType 有一个可选属性 autoGeneratePhraseQueries (默认=true)。如果我将 autoGeneratePhraseQueries 设置为 false,则一切正常。

    说明:

    schema.xml 中使用的字段类型:

    <fieldType name="edgytext" class="solr.TextField" autoGeneratePhraseQueries="false">
     <analyzer type="index">
       <tokenizer class="solr.KeywordTokenizerFactory"/>
       <filter class="solr.LowerCaseFilterFactory"/>
       <filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="25" />
     </analyzer>
     <analyzer type="query">
       <tokenizer class="solr.WhiteSpaceTokenizerFactory"/>
       <filter class="solr.LowerCaseFilterFactory"/>
       <filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="25" />
     </analyzer>
    </fieldType>
    

    如果您正在索引“惊喜”一词,则索引中包含以下标记:

    s, su, ,sur, surp, surpr, surpri, surpris, 惊喜

    如果您搜索“surpriese”(拼写错误),solr 会创建以下标记(匹配标记为粗体):

    ssusursurpsurpr惊喜,惊喜,惊喜,惊喜

    将创建的真实查询如下所示:

    mySearchField:s, mySearchField:su, mySearchField:sup .. 等等

    但如果您设置 autoGeneratePhraseQueries=true 将创建以下查询:

    mySearchField:"s su surp supr surprie surpries surpriese"

    这是一个短语查询,与索引词不匹配。

    【讨论】:

    • 其实我不明白这个解决方案,但我很好奇,我不知道那个参数;)你能从你的schema.xml 中发布你的mySearchField 字段定义吗?跨度>
    • @javanna 我为我的答案添加了解释。请注意,我最终使用了 EdgeNGramFilter
    • 谢谢,我去看看!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多