我正在使用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"。
您不需要像您所写的那样对查询进行标记化。检查您的schema.xml
中是否在索引时间和查询时间都应用了NGramFilterFactory
。然后,您使用的查询解析器会产生不同。有了LuceneQParser
,你会得到你想要的结果,但没有DisMax
和eDisMax
。
我用eDisMax
和debugQuery=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&mm=1
或小于25的值,则会得到您要查找的结果。
这个答案和您的答案的区别在于,对于EdgeNGramFilterFactory
,像mySearchField:werflow
这样的中缀查询不会返回任何结果,而对于NGramFilterFactory
,它会返回任何结果。
无论如何,如果你正在使用NGramFilterFactory
进行拼写更正,我强烈建议你也看看SpellCheckComponent
,它正是为此目的而制作的。
好的,我找到了一个快速简单的方法来解决这个问题。
fieldType具有可选属性autoGeneratePraseQueries(默认值为true)。如果我将autoGeneratePraseQueries设置为false,则一切正常。
解释:
schema.xml:中使用的fieldType
<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将创建以下令牌(匹配的令牌为粗体):
s,su、sur
将创建的真实查询如下所示:
mySearchField:su,mySearchField/su。。等等
但如果您将autoGeneratePraseQueries=true设置为true,则将创建以下查询:
mySearchField:"s su surp supr surprie surpries surprise"
这是一个短语查询,与索引项不匹配。