You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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+,可以用两次正则替换+词干化的组合过滤器:

  1. 先将+替换为临时标记,避免词干化器忽略带符号的单词;
  2. 对纯英文部分进行词干化;
  3. 再把临时标记替换回+。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 13:15:31