Skip to content

分词与分析器

什么是分词(Analysis)?

分词是全文检索的基础:把一段文本拆成一个个词(term),再建倒排索引。搜索时查询词也会经过同样的拆分,再与索引中的词匹配。分词由**分析器(Analyzer)**完成,一个分析器通常包含三部分:

  1. 字符过滤器(Character Filter):先对原始字符串做预处理(如去 HTML、映射字符)。
  2. 分词器(Tokenizer):把字符串切分成词元(token)序列。
  3. 词元过滤器(Token Filter):对词元再处理(如转小写、去停用词、同义词)。

内置分析器

Elasticsearch 自带多种分析器,常用有:

分析器说明
standard默认,按词切分、转小写,支持多语言,适合多数场景
simple按非字母切分,并转小写
whitespace按空白字符切分,不转小写
keyword不切分,整段当作一个词
stop在 simple 基础上去掉停用词(如 the、a)
pattern按正则切分

中文,standard 通常会把中文按单字切分,效果往往不理想,所以中文场景常用 IK 分词器 等第三方分析器。


测试分析器:_analyze API

不用真正建索引,就能看某段文本会被分成哪些词:

http
GET _analyze
{
  "analyzer": "standard",
  "text": "Elasticsearch 入门教程"
}

返回中会看到 tokens 数组,每个 token 有 tokenstart_offsetend_offset 等。也可以指定索引的某字段,使用该字段配置的 analyzer:

http
GET my_index/_analyze
{
  "field": "title",
  "text": "入门教程"
}

中文分词与 IK 分词器

默认中文的问题

使用 standard 对“ Elasticsearch 入门教程 ”分词时,英文会按词分,中文往往被拆成单字(如“入”“门”“教”“程”),检索和相关性都不理想。

IK 分词器

IK Analyzer 是常用的中文分词插件,支持:

  • ik_max_word:最细粒度切分,适合建索引(召回多)。
  • ik_smart:较粗粒度,适合搜索或短句(减少噪音)。

安装(示例,以 ES 7.x/8.x 为例):

  • 使用 Elasticsearch 插件命令:
    bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/vx.x.x/elasticsearch-analysis-ik-x.x.x.zip
    (具体版本号见 IK releases
  • 或下载 zip 解压到 plugins/ik,重启 ES。

安装后在 mapping 里指定 analyzer:

http
PUT /my_index
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart"
      }
    }
  }
}
  • analyzer:写入时用的分析器(建索引)。
  • search_analyzer:查询时用的分析器(可省略,默认用 analyzer)。

自定义词典

IK 支持扩展词和停用词,在 plugins/ik/config/ 下可配置:

  • IKAnalyzer.cfg.xml:指定扩展词典、远程词典等。
  • 扩展词:把业务专有词加进去,避免被拆散。
  • 停用词:过滤掉“的、了、是”等无检索意义的词。

自定义分析器

若内置和 IK 仍不满足需求,可在索引 settings 里自定义 analyzer,组合 character filter、tokenizer、token filter:

http
PUT /my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "type": "custom",
          "char_filter": ["html_strip"],
          "tokenizer": "standard",
          "filter": ["lowercase", "my_stop"]
        }
      },
      "filter": {
        "my_stop": {
          "type": "stop",
          "stopwords": ["a", "the"]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "content": {
        "type": "text",
        "analyzer": "my_analyzer"
      }
    }
  }
}

自定义分析器只能在创建索引时索引模板里定义,不能对已有索引随意修改。