这是执行您要求的一种方法:
字段类型
<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将拆分为单词aand b,并a b d拆分为a,b和d. 我们设置catenateAll="1",generateWordParts="0"所以单个单词被丢弃,产生一个单词。a并b成为ab和并成为。a_bdabd
查询分析器类似,但有细微差别。我们将值拆分为单词,除非我们不丢弃单词或将它们连接起来。相反,我们将单词传递给ShingleFilterFactory,它接受aandb并返回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".