如何在 Solr 4.8.1 中进行 "ends with" 搜索?
How to get an "ends with" search in Solr 4.8.1?
我有一个在 Solr 上建立索引的文档,其中包含以下字段:
{
"manufacturerSkuEndsWith": [
"DU351118DR0"
]
}
我的目标是在 manufacturerSkuEndsWith
字段上进行“结尾为”搜索。例如,以下查询应匹配上述值:DR0
、8DR0
、18DR0
、118DR0
...但这些查询不应匹配:DU35
, 118DR
, 118
...
我的问题是查询 118
匹配该文档,即使 DU351118DR0
没有以 118
结尾。
我的 Solr & Lucene 版本是 4.8.1。我发现在此版本中不再支持 EdgeNGramTokenizer 的 side="back"
:LUCENE-3907。在此线程中,他们建议使用 ReverseStringFilter
来获得类似于带有 side="back"
的 EdgeNGramTokenizer 的行为,所以这就是我在 schema.xml
中配置 manufacturerSkuEndsWith
字段的方式:
<field indexed="true" multiValued="true" name="manufacturerSkuEndsWith" stored="true" type="smccTextReversedNGram"/>
<copyField dest="manufacturerSkuEndsWith" source="ManufacturerSku"/>
<fieldType class="solr.TextField" name="smccTextReversedNGram" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.NGramTokenizerFactory" maxGramSize="10" minGramSize="3"/>
<filter class="solr.SynonymFilterFactory" expand="true" ignoreCase="true" synonyms="synonyms.txt"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.ReverseStringFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.ReverseStringFilterFactory"/>
</analyzer>
</fieldType>
但此配置不执行“结尾为”搜索:
我怎样才能获得这种类型的搜索?
您使用的是 NGramTokenizer,而不是示例中所示的 EdgeNGramFilter。 NgramTokenizer 也会从字符串内部生成标记,而不仅仅是从边缘生成标记。
要获得您正在寻找的行为,您必须有一个 KeywordTokenizer(它将输入保持为单个标记),然后使用 ReverseStringFilter 来反转它 - 在使用 EdgeNGramFilter 从现在反转字符串的开头:
foo -> oof -> o, oo, oof
然后您可以 运行 这些通过反向字符串过滤器再次获得索引的“正确”版本:
-> o, oo, foo
.. 或者你可以按照你在你的领域所做的那样,反转输入字符串:
foo -> oof -> matches the oof token
我有一个在 Solr 上建立索引的文档,其中包含以下字段:
{
"manufacturerSkuEndsWith": [
"DU351118DR0"
]
}
我的目标是在 manufacturerSkuEndsWith
字段上进行“结尾为”搜索。例如,以下查询应匹配上述值:DR0
、8DR0
、18DR0
、118DR0
...但这些查询不应匹配:DU35
, 118DR
, 118
...
我的问题是查询 118
匹配该文档,即使 DU351118DR0
没有以 118
结尾。
我的 Solr & Lucene 版本是 4.8.1。我发现在此版本中不再支持 EdgeNGramTokenizer 的 side="back"
:LUCENE-3907。在此线程中,他们建议使用 ReverseStringFilter
来获得类似于带有 side="back"
的 EdgeNGramTokenizer 的行为,所以这就是我在 schema.xml
中配置 manufacturerSkuEndsWith
字段的方式:
<field indexed="true" multiValued="true" name="manufacturerSkuEndsWith" stored="true" type="smccTextReversedNGram"/>
<copyField dest="manufacturerSkuEndsWith" source="ManufacturerSku"/>
<fieldType class="solr.TextField" name="smccTextReversedNGram" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.NGramTokenizerFactory" maxGramSize="10" minGramSize="3"/>
<filter class="solr.SynonymFilterFactory" expand="true" ignoreCase="true" synonyms="synonyms.txt"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.ReverseStringFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
<filter class="solr.ReverseStringFilterFactory"/>
</analyzer>
</fieldType>
但此配置不执行“结尾为”搜索:
我怎样才能获得这种类型的搜索?
您使用的是 NGramTokenizer,而不是示例中所示的 EdgeNGramFilter。 NgramTokenizer 也会从字符串内部生成标记,而不仅仅是从边缘生成标记。
要获得您正在寻找的行为,您必须有一个 KeywordTokenizer(它将输入保持为单个标记),然后使用 ReverseStringFilter 来反转它 - 在使用 EdgeNGramFilter 从现在反转字符串的开头:
foo -> oof -> o, oo, oof
然后您可以 运行 这些通过反向字符串过滤器再次获得索引的“正确”版本:
-> o, oo, foo
.. 或者你可以按照你在你的领域所做的那样,反转输入字符串:
foo -> oof -> matches the oof token