如何让Solr通过短词搜索?
How to make Solr search by short words?
我有一个项目显示“4k 显示器”,当我搜索“4k 显示器”时,该项目似乎没有被优先考虑,其他带有 "display"(没有 4k)的项目出现了。
如果我搜索“4k”,什么也没有显示。
我应该更改配置中的哪些内容来解决此问题?
更新:这是文本类型部分的样子,可能是由太阳黑子设置的gem。
<fieldType name="text" class="solr.TextField" omitNorms="false">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<!--<filter class="solr.StandardFilterFactory"/>-->
<filter class="solr.LowerCaseFilterFactory"/>
<!--<filter class="solr.KStemFilterFactory"/>-->
<filter class="solr.NGramFilterFactory" minGramSize="3" maxGramSize="7"/>
</analyzer>
</fieldType>
minGram 大小看起来像罪魁祸首?
您的 NGramFilter 配置为仅保留至少包含三个字符的标记:
<filter class="solr.NGramFilterFactory" minGramSize="3" maxGramSize="7"/>
4k
只有两个,因此过滤器不会为该输入生成任何标记。如果您希望它仍然保持 4k
,即使它不够长,您可以尝试将 preserveOriginal="true"
添加到参数中(根据 filterfactory 的 javadoc - 但代码似乎在寻找一个名为 keepShortTerm
的参数,所以如果第一个失败请尝试)。
这将需要重新索引您的内容,以便为您的文档提供新的标记。
那么让我们浏览一下您的分析链。
首先是标准分词器。它将在空格处拆分。
所以“4K显示”会分裂成两个token
4k,display
下一个是lowercaseFilter。这会将标记小写,因此在这种情况下,不会有任何变化,因为它已经小写了。所以到这一步结束时,您仍然拥有相同的两个令牌
4k,display
现在是 NGramFilterFactory,它将开始像这样创建标记。
例如,如果您有一个名为 "abcd"
的令牌
Ngram 将生成这样的标记。
a,ab,abc,abcd,b, bc,bcd,c,cd,d
但是在ngram字段类型中定义了另一个选项
minGramSize="3" maxGramSize="7"
这意味着只保留最小长度为 3 且最大长度为 7 的标记。
所以在上面的例子中你只会看到
abc,abcd,bcd
到此为止。
现在让我们把它应用到你的案例中。经过小写过滤后,我们有两个标记
4k,display
在两者上应用 Ngram 将产生以下结果
4,4k,k,d,di,dis,disp,displ,displa,display,i,isp and so on . You get
the idea.
但由于 miggram 大小为 3。将从您的索引中删除 4 和 4k。因此您无法使用 4k 进行搜索。因为它从来没有在索引中。
您的索引只有以 dis
开头的值,例如
dis,disp,displ,displa,display
为了解决这个问题。首先,您需要了解您希望如何搜索数据。
你真的需要 NGRamtokenizer 吗?
例如,如果您只想获得精确匹配。例如,当您查询“4k 显示”时,您只需要具有“4k”或 "display" 或“4k 显示”的结果,那么您需要更改分析链。
在这种情况下,从您的分析链中注释掉 NGram 并重建索引并再次尝试查询。
我有一个项目显示“4k 显示器”,当我搜索“4k 显示器”时,该项目似乎没有被优先考虑,其他带有 "display"(没有 4k)的项目出现了。
如果我搜索“4k”,什么也没有显示。
我应该更改配置中的哪些内容来解决此问题?
更新:这是文本类型部分的样子,可能是由太阳黑子设置的gem。
<fieldType name="text" class="solr.TextField" omitNorms="false">
<analyzer>
<tokenizer class="solr.StandardTokenizerFactory"/>
<!--<filter class="solr.StandardFilterFactory"/>-->
<filter class="solr.LowerCaseFilterFactory"/>
<!--<filter class="solr.KStemFilterFactory"/>-->
<filter class="solr.NGramFilterFactory" minGramSize="3" maxGramSize="7"/>
</analyzer>
</fieldType>
minGram 大小看起来像罪魁祸首?
您的 NGramFilter 配置为仅保留至少包含三个字符的标记:
<filter class="solr.NGramFilterFactory" minGramSize="3" maxGramSize="7"/>
4k
只有两个,因此过滤器不会为该输入生成任何标记。如果您希望它仍然保持 4k
,即使它不够长,您可以尝试将 preserveOriginal="true"
添加到参数中(根据 filterfactory 的 javadoc - 但代码似乎在寻找一个名为 keepShortTerm
的参数,所以如果第一个失败请尝试)。
这将需要重新索引您的内容,以便为您的文档提供新的标记。
那么让我们浏览一下您的分析链。 首先是标准分词器。它将在空格处拆分。 所以“4K显示”会分裂成两个token
4k,display
下一个是lowercaseFilter。这会将标记小写,因此在这种情况下,不会有任何变化,因为它已经小写了。所以到这一步结束时,您仍然拥有相同的两个令牌
4k,display
现在是 NGramFilterFactory,它将开始像这样创建标记。 例如,如果您有一个名为 "abcd"
的令牌Ngram 将生成这样的标记。
a,ab,abc,abcd,b, bc,bcd,c,cd,d
但是在ngram字段类型中定义了另一个选项
minGramSize="3" maxGramSize="7"
这意味着只保留最小长度为 3 且最大长度为 7 的标记。 所以在上面的例子中你只会看到
abc,abcd,bcd
到此为止。
现在让我们把它应用到你的案例中。经过小写过滤后,我们有两个标记
4k,display
在两者上应用 Ngram 将产生以下结果
4,4k,k,d,di,dis,disp,displ,displa,display,i,isp and so on . You get the idea.
但由于 miggram 大小为 3。将从您的索引中删除 4 和 4k。因此您无法使用 4k 进行搜索。因为它从来没有在索引中。
您的索引只有以 dis
开头的值,例如
dis,disp,displ,displa,display
为了解决这个问题。首先,您需要了解您希望如何搜索数据。
你真的需要 NGRamtokenizer 吗?
例如,如果您只想获得精确匹配。例如,当您查询“4k 显示”时,您只需要具有“4k”或 "display" 或“4k 显示”的结果,那么您需要更改分析链。
在这种情况下,从您的分析链中注释掉 NGram 并重建索引并再次尝试查询。