📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

在 Easysearch(以及 Elasticsearch)的社区讨论中,这几乎是一个月经贴:“我们要上中文搜索,是不是必须安装 IK 分词器?”

很多新手开发者的第一反应是:“当然!中文没有空格,不装分词器怎么搜?”

但答案其实是:不一定。 甚至在某些特定场景下,不装分词器反而效果更好。

本文将从搜索引擎的底层索引原理出发,探讨在不安装第三方分词插件的情况下,Easysearch 如何处理中文,以及我们何时该“装”,何时该“裸奔”。

方案一:“裸奔” —— 使用默认的 Standard Analyzer #

Easysearch 默认的 standard 分词器虽然是为西方语言设计的,但它对中文的处理逻辑非常简单粗暴:按字切分(Unigram)

原理分析 #

当你索引“程序员”这三个字时,standard 分词器会将其切分为:
[程, 序, 员]

当你搜索“程序”时,查询语句也会被切分为:
[程, 序]

只要你的查询类型使用得当(例如使用 match_phrase 短语匹配),完全可以搜出来!

GET /_search
{
  "query": {
    "match_phrase": {
      "content": "程序"
    }
  }
}
  • 优点
    • 零配置:不需要安装任何插件,开箱即用。
    • 100% 查全率:因为每个字都被索引了,绝对不会因为分词器“切错词”导致搜不到。比如“奥利给”这种新词,IK 可能切不开,但按字切分一定能匹配到。
  • 缺点
    • 索引膨胀:虽然中文词汇量大,但常用汉字只有几千个。按字切分会导致倒排索引中的 Term 列表非常长(尽管 Term Dictionary 会压缩,但 Posting List 会很长)。
    • 语义缺失:无法理解“和服”与“和/服”的区别。
    • 噪音干扰:搜索“上海”,可能会匹配到“海上”(如果是简单的 match query 而非 phrase query)。

适用场景

  • 简单的站内搜索,数据量不大(百万级以下)。
  • 对精准度要求不高,只要包含关键字就能出来的场景。

方案二:暴力美学 —— 通配符与正则 (Wildcard) #

如果不使用分词(将字段设为 keyword 类型),我们还可以通过 wildcard(通配符)查询来实现类似 SQL 中 LIKE '%keyword%' 的效果。

GET /_search
{
  "query": {
    "wildcard": {
      "content": "*程序员*"
    }
  }
}
  • 原理
    • keyword 类型不分词,整个句子作为一个 Term 存入倒排索引。
    • 查询时,引擎需要扫描 Term Dictionary 中的所有 Term 进行正则匹配。
  • 致命弱点
    • 性能灾难:首部带通配符的查询(Leading Wildcard)无法利用前缀索引,会导致全表扫描。在海量数据下,这会直接拖垮集群。
  • 结论
    • 绝对不推荐在高并发或大数据量的搜索业务中使用。

方案三:原生的高阶玩法 —— N-Gram 分词 #

如果你不想安装插件,又想获得比“按字切分”更好的体验,Easysearch 内置的 ngram Tokenizer 是一个被低估的神器。

什么是 N-Gram? #

它是一种基于滑动窗口的切分方式。假设设置 min_gram=2, max_gram=2(即 Bigram),“搜索引擎”会被切分为:
[搜索, 索引, 引擎]

配置示例 (DSL) #

PUT /my_ngram_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_ngram_analyzer": {
          "tokenizer": "my_tokenizer"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "ngram",
          "min_gram": 2,
          "max_gram": 2,
          "token_chars": ["letter", "digit"]
        }
      }
    }
  }
}
  • 优点
    • 原生支持:无需安装插件,纯配置即可实现。
    • 解决错别字:N-Gram 对拼写错误有很好的容错性。
    • 支持中缀搜索:不需要通配符也能匹配到词语中间的字。
  • 缺点
    • 空间换时间:索引大小会急剧膨胀(通常是原文本的数倍)。
    • 查准率低:容易产生误匹配。比如搜“索引”,也能匹配到“搜索引擎”。

既然都有替代方案,为什么还要装 IK 分词器? #

既然 Standard 和 N-Gram 都能用,为什么 IK、Jieba、HanLP 这些中文分词插件依然是标配?

核心在于语义理解(Semantic Understanding)**和**相关性评分(Relevance Scoring)

1. 歧义消除 #

经典的中文歧义句:“南京市长江大桥”。

  • Standard/N-Gram:只能机械切分,无法理解语义。
  • 智能分词器:能根据词库和统计模型,将其正确识别为 [南京市, 长江大桥],而不是 [南京市长, 江大桥]
    • 如果你搜“市长”,智能分词器不会把“南京市长江大桥”推给你;但 Standard 分词器(按字搜)可能会因为包含“市”、“长”两个字而误判。

2. 停用词处理 #

中文里充满了“的”、“了”、“呢”等无实义的助词。智能分词器可以配置停用词表,在建立索引时直接丢弃这些词,既节省了空间,又排除了噪音,让评分算法(BM25)更聚焦于核心关键词。

总结与建议 #

回到标题的问题:Easysearch 中文搜索一定要装分词器吗?

决策指南:

  1. 必须要装
    • 面向 C 端用户的电商、内容平台(对搜索相关性要求极高)。
    • 需要处理复杂的自然语言查询(如“推荐几款性价比高的红色手机”)。
    • 数据量级达到千万/亿级,需要通过分词压缩索引体积。
  2. 可以不装(使用 Standard)
    • 简单的后台管理系统(CMS),只查人名、ID、特定短语。
    • 日志检索系统(主要靠精确匹配)。
  3. 可以不装(使用 N-Gram)
    • 数据量不大,但需要极强的“模糊搜索”能力(输错字也能搜到)。

在闭源的商业软件环境下,保持架构的简洁性往往很重要。如果你的需求仅仅是“能搜到”,那么 Easysearch 原生的能力或许已经绰绰有余。不要为了分词而分词,适合业务场景的,才是最好的。