Solr关键词子串匹配查询逻辑实现问题咨询
解决方案
你的核心需求是:索引时将逗号分隔的每组关键词作为独立的不可分割单元,查询时只要查询文本中包含某组完整的关键词(连续子串),就命中对应文档;同时单独搜索某组关键词时,仅返回精确匹配该组的文档。
问题根源
你之前的配置存在三个关键问题:
- 索引端未处理逗号后的空格,导致生成的token带前导空格(比如
phone),和查询端生成的无空格token(phone)无法匹配; - 查询端ShingleFilter可能未开启
outputUnigrams,导致单个词的关键词组(比如文档2的brand)无法被匹配; - 未统一大小写,可能导致大小写不匹配的问题。
正确的字段类型配置
<fieldType name="keyword_group" class="solr.TextField" positionIncrementGap="100"> <!-- 索引端:按逗号+可选空格分割,得到干净的关键词组,统一小写 --> <analyzer type="index"> <tokenizer class="solr.PatternTokenizerFactory" pattern=",\s*"/> <filter class="solr.LowerCaseFilterFactory"/> </analyzer> <!-- 查询端:按空格拆分,统一小写,生成所有可能的连续词组合(含单个词) --> <analyzer type="query"> <tokenizer class="solr.WhitespaceTokenizerFactory"/> <filter class="solr.LowerCaseFilterFactory"/> <filter class="solr.ShingleFilterFactory" maxShingleSize="10" <!-- 设置足够覆盖最长关键词组的长度,比如10 --> minShingleSize="2" outputUnigrams="true"/> <!-- 必须开启,保留单个词的token --> </analyzer> </fieldType>
字段配置
将你的关键词字段指定为这个类型:
<field name="keywords" type="keyword_group" indexed="true" stored="true"/>
效果验证
- 搜索
brand:查询端生成单个词brand,仅匹配文档2的brandtoken,返回文档2; - 搜索
brand tv:查询端生成brand、tv、brand tv三个词项,匹配文档1的brand tv和文档2的brand,返回1、2项; - 搜索
grey brand tv:查询端生成包括brand、brand tv在内的词项,匹配文档1和2; - 搜索
foo bar brand tv baz:查询端生成的词项中包含brand和brand tv,匹配文档1和2; - 搜索
phone case:查询端生成phone、case、phone case,匹配文档1和3的phonetoken,返回1、3项。
注意事项
maxShingleSize设置为你业务中最长关键词组的词数(比如10),避免出现超出限制的场景;- 如果需要支持更长的关键词组,适当增大
maxShingleSize即可,只要不超过Solr的配置限制,实际性能影响可以忽略。
内容的提问来源于stack exchange,提问作者omg_me
相关产品推荐
相关产品推荐

