Appearance
Elasticsearch 核心概念与索引设计:Index、Document、Mapping、Analyzer、Shard 怎么理解
Elasticsearch 很容易给人一种“像数据库,但又不完全像数据库”的感觉。
很多团队第一次把它接进业务时,只觉得:
- 能搜到结果就行
- DSL 先抄着写
- Mapping 让它自动生成
但这种思路到了线上很快就会遇到这些问题:
- 搜索结果不准
- 聚合很慢
- 分词不符合预期
- 索引膨胀
- 字段越来越乱
- 集群规模不算大,查询却越来越吃力
这些问题看起来分散,根子往往都在索引设计阶段。
先说结论
理解 Elasticsearch,最值得先抓住的不是一堆 DSL,而是下面这 5 个概念:
IndexDocumentMappingAnalyzerShard
其中真正决定长期可维护性的,通常不是你会不会写查询语句,而是:
- Mapping 设计
- 分词策略
- 分片规划
一、Index 和 Document 不只是“库表替代品”
可以先做一个粗略类比:
Index像逻辑上的数据集合Document像一条被索引的记录
但这个类比只能帮助入门,不能直接把 ES 按 MySQL 去理解。因为 Elasticsearch 的目标更偏:
- 检索效率
- 文本搜索
- 多维过滤和聚合
这意味着你在设计索引时更应该先问:
- 这批数据是拿来全文搜索的
- 还是拿来精确过滤的
- 还是既要检索又要聚合分析
问题问错了,后面字段设计大概率也会歪。
二、Mapping 为什么是基础中的基础
Mapping 决定了字段如何被存储、如何被索引、能不能聚合、能不能排序、查询时该走什么路径。
常见问题几乎都和它有关,例如:
- 某个字段为什么不能聚合
- 某个字段为什么搜索结果不对
- 某个字段为什么占空间很大
真正线上代价最大的,往往不是某条查询写得不好,而是:
- 字段类型从一开始就定义错了
- 字段数量无限增长
- 动态 Mapping 把很多脏数据也吞进了索引
所以 ES 设计里一个非常重要的原则是:
- 字段类型和字段用途要提前设计清楚
三、text 和 keyword 为什么必须分清
这几乎是入门 ES 时最常见的边界问题。
text
适合:
- 全文检索
- 分词匹配
keyword
适合:
- 精确匹配
- 排序
- 聚合
很多字段其实都应该先问用途,而不是先问“它是不是字符串”:
- 是拿来搜索全文,还是拿来过滤和聚合
如果这个边界没分清,后面会产生很多“能搜但不能聚合”或“能聚合但搜索体验差”的问题。
典型例子是:
- 用户名、标签、状态码、订单号,多数时候更偏
keyword - 标题、正文、描述、评论内容,更偏
text
而很多真正实用的设计会同时保留两种能力:
- 能全文搜索
- 也能按原值聚合或排序
这类能力要在索引设计阶段就想清楚,等线上再补,代价通常更高。
四、Analyzer 为什么决定搜索体验
Analyzer 决定文本怎么被拆词。
对于中文搜索尤其重要,因为:
- 不同分词方式,直接影响召回结果和匹配粒度
所以搜索效果不好时,不一定是 DSL 写错了,很可能是:
- 建索引时分词策略就不合理
特别是中文搜索,经常会碰到下面几类问题:
- 搜索词切得太细,误召回太多
- 搜索词切得太粗,召回不足
- 索引分词和搜索分词不一致
- 同义词、简称、英文缩写没有统一处理
很多团队把“搜索效果调优”理解成改查询,其实大多数时候要回头看:
- 建索引时用了什么 analyzer
- 查询时用了什么 analyzer
- 业务到底追求召回优先,还是精确优先
五、Shard 不只是扩容参数,也决定查询成本
Elasticsearch 的数据会分布到多个 shard 上。
分片的作用包括:
- 分布式存储
- 并行查询
- 扩展容量
但分片不是越多越好。
因为分片本身也有管理成本:
- 元数据开销
- 查询协调成本
- 小分片过多导致集群负担上升
很多线上集群并不是被“单个超大索引”拖慢,而是被“很多小而碎的 shard”拖累。
所以分片规划应该结合:
- 数据量
- 查询模式
- 集群规模
一起判断。
如果是日志、埋点、审计类数据,还要再加上一层:
- 生命周期和滚动索引策略怎么设计
六、索引设计时更实用的几个问题
1. 这个字段是拿来搜,还是拿来筛选
这决定你更偏向:
text- 还是
keyword
2. 是否需要排序和聚合
如果需要,字段设计要特别小心。
3. 数据生命周期是否很明显
例如日志索引、按天按月滚动索引,就和业务主数据索引思路不同。
4. 会不会出现大量动态字段
动态字段失控,很容易让 mapping 膨胀。
5. 这个索引到底偏搜索、偏过滤,还是偏分析
很多系统同时把 ES 用在:
- 业务搜索
- 运维日志
- 可视化报表
如果这三类模型混在同一套索引设计里,后面调优会越来越困难。
七、Elasticsearch 更适合什么场景
更适合:
- 商品搜索
- 文档检索
- 日志搜索
- 多条件全文搜索
- 聚合分析
不适合直接替代:
- 强事务型数据库
- 高频强一致 OLTP 核心数据存储
尤其不要把它理解成“比 MySQL 更快的万能查询库”。ES 的强项是围绕索引做检索,不是替代事务数据库承担核心业务真相源。
八、几个常见误区
1. 把 ES 当 MySQL 的全文版
它有很多相似功能,但建模思路和性能边界并不一样。
2. Mapping 不做规划,全靠动态生成
前期快,后期代价通常很大。
3. 分片开得很大很细,以为以后一定更好扩
分片过多本身就会拖累集群。
4. 把所有字符串字段都做成 text
这样会导致精确过滤、聚合、排序很快遇到限制。
5. 搜索效果不好,只会改查询语句
很多问题其实出在分词和字段建模,不在 DSL 本身。
九、线上做索引设计时更推荐的顺序
如果你是从零开始建一个搜索或日志系统,更实用的顺序通常是:
- 先确定数据用途,是搜索为主还是过滤聚合为主。
- 再梳理核心字段,明确哪些字段要全文检索,哪些字段要精确过滤。
- 然后设计 Mapping,控制动态字段边界。
- 再决定 analyzer 和多字段策略。
- 最后再规划分片数、索引滚动和生命周期。
这样你是在围绕业务检索模型建设索引,而不是围绕某个现成模板堆配置。
一句话总结
Elasticsearch 用得稳不稳,关键从来不只是会不会写 DSL,而在于索引设计有没有把字段用途、分词策略、分片规模和生命周期一起想清楚。
底座搭正了,查询调优会越来越顺;底座搭歪了,后面再怎么补参数,也只是不断给问题贴创可贴。