这是执行您要求的一种方法:
字段类型
<fieldType name="exact" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.WordDelimiterFilterFactory" splitOnCaseChange="0" splitOnNumerics="0" preserveOriginal="0" generateWordParts="0" catenateAll="1" />
</analyzer>
<analyzer type="query">
<tokenizer class="solr.KeywordTokenizerFactory"/>
<filter class="solr.WordDelimiterFilterFactory" splitOnCaseChange="0" splitOnNumerics="0" preserveOriginal="0" generateWordParts="1" catenateAll="0" />
<filter class="solr.ShingleFilterFactory" outputUnigrams="true" outputUnigramsIfNoShingles="true" tokenSeparator="" maxShingleSize="99"/>
</analyzer>
</fieldType>
解释:
索引分析器用于WordDelimiterFilterFactory
将字段值拆分为单词。因此,使用您的示例,a b
将拆分为单词a
and b
,并a b d
拆分为a
,b
和d
. 我们设置catenateAll="1"
,generateWordParts="0"
所以单个单词被丢弃,产生一个单词。a
并b
成为ab
和并成为。a
_b
d
abd
查询分析器类似,但有细微差别。我们将值拆分为单词,除非我们不丢弃单词或将它们连接起来。相反,我们将单词传递给ShingleFilterFactory
,它接受a
andb
并返回a
, b
, and ab
。
我们使用 shingles 而不是串联的原因是允许a b c
匹配a b
和b c
。如果你只想a b c
匹配a b c
,设置catenateAll="1"
和删除 shingle 工厂。
使用此配置,a b
将仅匹配a
、b
和a b
(而不是a b d
)。此外,a b c
将匹配a
, b
, c
, a b
, b c
, 和a b c
. 还应该注意的是ab
会匹配a b
。如果其中任何一个不是您想要的,您应该能够配置 shingle 和 word 过滤器工厂来完全满足您的需要。
编辑:这个答案的早期版本使用魔法值来标记值的开始和结束。事实证明这是不必要的;只需将这些值连接在一起就足以防止a b
匹配a b d
。
编辑 2(索引分析器修复):WhitespaceTokenizerFactory
应该是KeywordTokenizerFactory
. 此外,WordDelimiterFilterFactory
应该有catenateAll="0"
.