Elasticsearch含特殊后缀词汇的词干提取方案咨询
解决方案
针对你遇到的whitespace分词器搭配searchkick_stemmer时,company+无法正确词干化的问题,以下是两种针对性方案,无需使用生成过多token的edge-gram:
方案1:拆分出+作为独立token,得到["compani", "+"]
通过添加word_delimiter过滤器,先将+从单词中拆分出来,再对拆分后的英文单词进行词干化。在Searchkick中可这样配置:
searchkick settings: { analysis: { analyzer: { custom_stem_analyzer: { tokenizer: "whitespace", filter: ["custom_word_delimiter", "searchkick_stemmer"] } }, filter: { custom_word_delimiter: { type: "word_delimiter", split_on_punctuation: true, # 按标点拆分,包含+ preserve_original: false, # 不保留原始的company+ catenate_all: false, # 不合并拆分后的token split_on_numerics: false, # 避免数字拆分(如果不需要) split_on_case_change: false # 避免大小写拆分(如果不需要) } } } }, mappings: { properties: { # 替换成你需要处理的字段名 target_field: { type: "text", analyzer: "custom_stem_analyzer" } } }
这个配置会先把company+拆分为["company", "+"],再将company词干化为compani,最终输出符合需求的token数组。
方案2:保留+后缀,得到compani+
如果需要将company+直接处理为compani+,可以用两次正则替换+词干化的组合过滤器:
- 先将
+替换为临时标记,避免词干化器忽略带符号的单词; - 对纯英文部分进行词干化;
- 再把临时标记替换回
+。
Searchkick配置示例:
searchkick settings: { analysis: { analyzer: { stem_with_plus_analyzer: { tokenizer: "whitespace", filter: ["pre_replace_plus", "searchkick_stemmer", "post_replace_plus"] } }, filter: { pre_replace_plus: { type: "pattern_replace", pattern: "([a-zA-Z]+)\\+", replacement: "$1__TEMP_PLUS__" }, post_replace_plus: { type: "pattern_replace", pattern: "([a-zA-Z]+)__TEMP_PLUS__", replacement: "$1+" } } } }
流程说明:company+ → company__TEMP_PLUS__ → 词干化为compani__TEMP_PLUS__ → compani+,最终得到带后缀的词干化结果。
方案3:自定义脚本过滤器(更灵活)
如果需要处理更复杂的符号场景,可使用Elasticsearch的脚本过滤器,直接在token层面处理:
searchkick settings: { analysis: { analyzer: { script_stem_analyzer: { tokenizer: "whitespace", filter: ["script_plus_handler", "searchkick_stemmer"] } }, filter: { script_plus_handler: { type: "script", script: { source: """ import org.apache.lucene.analysis.en.PorterStemmer; def stemmer = new PorterStemmer(); if (token.text.contains('+')) { def parts = token.text.splitOnToken('+'); def stemmedWord = stemmer.stem(parts[0]); token.setText(stemmedWord + '+'); } return token; """ } } } } }
这个脚本会自动识别带+的token,拆分后词干化英文部分,再拼接+返回,适合需要自定义逻辑的场景。
内容的提问来源于stack exchange,提问作者akmalcm
相关产品推荐
相关产品推荐

