Solr 9.10 Terms组件联想无法匹配重音特殊字符问题
Solr 9.10 Terms组件联想功能问题解决
问题场景
在Solr 9.10中使用Terms组件实现联想功能,期望输入短语“Romance rose”时,能联想出带重音的“Romance rosé”。当前输入“Romance ros”可得到目标结果,但输入完整短语“Romance rose”时无法匹配。
当前使用的字段类型配置如下:
<fieldType name="lowercasewithtrim" class="solr.TextField" positionIncrementGap="100"> <analyzer type="index"> <tokenizer class="solr.KeywordTokenizerFactory"/> <filter class="solr.LowerCaseFilterFactory" /> <filter class="solr.TrimFilterFactory" /> <!-- Remove apostrophes and other punctuation --> <filter class="solr.WordDelimiterGraphFilterFactory" splitOnCaseChange="0" splitOnNumerics="0" stemEnglishPossessive="1" generateWordParts="0" generateNumberParts="0" catenateWords="0" catenateNumbers="0" catenateAll="0" preserveOriginal="1"/> <!--filter class="solr.ASCIIFoldingFilterFactory" preserveOriginal="true"/--> <filter name="synonymGraph" synonyms="synonyms.txt" ignoreCase="true" expand="true"/> <filter name="flattenGraph"/> <!-- required on index analyzers after graph filters --> </analyzer> <analyzer type="query"> <tokenizer class="solr.KeywordTokenizerFactory"/> <filter class="solr.LowerCaseFilterFactory" /> <filter class="solr.TrimFilterFactory" /> <!-- Remove apostrophes and other punctuation --> <filter class="solr.WordDelimiterGraphFilterFactory" splitOnCaseChange="0" splitOnNumerics="0" stemEnglishPossessive="1" generateWordParts="0" generateNumberParts="0" catenateWords="0" catenateNumbers="0" catenateAll="0" preserveOriginal="1"/> <!--filter class="solr.ASCIIFoldingFilterFactory" preserveOriginal="true"/--> <filter name="synonymGraph" synonyms="synonyms.txt" ignoreCase="true" expand="true"/> </analyzer> </fieldType>
同义词表中已配置带重音的é与普通e的映射。
问题原因
- 分词器限制:当前使用
KeywordTokenizerFactory,会将整个输入短语作为单个token处理。同义词规则仅映射单个字符e和é,无法作用于完整短语token中的末尾e。 - 前缀匹配特性:输入“Romance ros”时,Terms组件的前缀匹配逻辑会命中“Romance rosé”的前缀部分,因此能返回结果;但输入完整的“Romance rose”时,完整token与索引中的“Romance rosé”不匹配,同义词规则也无法触发转换。
解决方案
方案一:改用分词器拆分单词(推荐)
将KeywordTokenizerFactory替换为WhitespaceTokenizerFactory,让每个单词单独成为一个token,这样同义词规则就能作用于最后一个单词“rose”,将其转换为“rosé”。
修改后的字段类型配置:
<fieldType name="lowercasewithtrim" class="solr.TextField" positionIncrementGap="100"> <analyzer type="index"> <tokenizer class="solr.WhitespaceTokenizerFactory"/> <filter class="solr.LowerCaseFilterFactory" /> <filter class="solr.TrimFilterFactory" /> <filter class="solr.WordDelimiterGraphFilterFactory" splitOnCaseChange="0" splitOnNumerics="0" stemEnglishPossessive="1" generateWordParts="0" generateNumberParts="0" catenateWords="0" catenateNumbers="0" catenateAll="0" preserveOriginal="1"/> <!-- 可选:自动处理重音字符,无需手动配置同义词 --> <!-- <filter class="solr.ASCIIFoldingFilterFactory" preserveOriginal="true"/> --> <filter name="synonymGraph" synonyms="synonyms.txt" ignoreCase="true" expand="true"/> <filter name="flattenGraph"/> <!-- index分析器中使用图过滤器后必须添加 --> </analyzer> <analyzer type="query"> <tokenizer class="solr.WhitespaceTokenizerFactory"/> <filter class="solr.LowerCaseFilterFactory" /> <filter class="solr.TrimFilterFactory" /> <filter class="solr.WordDelimiterGraphFilterFactory" splitOnCaseChange="0" splitOnNumerics="0" stemEnglishPossessive="1" generateWordParts="0" generateNumberParts="0" catenateWords="0" catenateNumbers="0" catenateAll="0" preserveOriginal="1"/> <!-- <filter class="solr.ASCIIFoldingFilterFactory" preserveOriginal="true"/> --> <filter name="synonymGraph" synonyms="synonyms.txt" ignoreCase="true" expand="true"/> </analyzer> </fieldType>
方案二:添加完整短语同义词(不推荐)
如果必须保留KeywordTokenizerFactory,可以在同义词表中添加完整短语的映射:
romance rose, romance rosé
这种方式需要手动维护所有可能的短语组合,扩展性差。
方案三:启用重音自动折叠
取消字段类型配置中ASCIIFoldingFilterFactory的注释,该过滤器会自动将重音字符转换为非重音形式,同时保留原词。此时无需单独配置e和é的同义词,Terms组件可基于折叠后的token进行联想,返回包含重音的原词。
内容的提问来源于stack exchange,提问作者Michael Guzman
相关产品推荐
相关产品推荐

