Elasticsearch 实战:文档设计原则与最佳实践
- 一、前言
- 二、基础概念:什么是 ES 文档?
- 2.1 文档定义
- 2.2 文档核心特征
- 2.3 文档写入与查询流程图
- 三、Elasticsearch 文档设计 7 大核心原则
- 3.1 原则1:优先反规范化(冗余数据)
- 3.2 原则2:字段越少越好,避免过度嵌套
- 3.3 原则3:字段类型必须精准定义
- 3.4 原则4:文档大小要适中
- 3.5 原则5:禁止频繁修改文档
- 3.6 原则6:结构扁平化,少用嵌套
- 3.7 原则7:提前规划,禁止字段冲突
- 四、文档字段设计最佳实践(最重要章节)
- 4.1 文本字段必须使用 text + keyword 组合
- 4.2 精准匹配字段必须用 keyword
- 4.3 数字类型选择要合理
- 4.4 时间必须使用 date 类型
- 4.5 布尔类型用 boolean
- 4.6 禁用不必要的字段属性
- 4.7 统一字段命名规范
- 五、文档结构设计最佳实践
- 5.1 优先扁平化结构(推荐)
- 5.2 少用嵌套类型 nested
- 5.3 少用对象嵌套
- 5.4 大文本字段单独存放
- 六、文档大小与数量控制规范
- 6.1 最佳文档大小
- 6.2 禁止超大文档
- 6.3 大批量数据必须批量写入
- 七、避免动态映射陷阱(必看)
- 7.1 生产环境必须关闭动态映射
- 7.2 禁止 ES 自动生成字符串类型
- 八、高可用与安全最佳实践
- 8.1 文档 ID 设计
- 8.2 不存储原始不需要的字段
- 8.3 敏感数据不存入ES
- 九、高性能搜索最佳实践
- 9.1 只查询需要的字段 `_source`
- 9.2 禁止 `*` 匹配所有字段
- 9.3 长文本字段禁用分词
- 十、文档设计反例(禁止使用)
- 10.1 反例1:所有字段都用 text
- 10.2 反例2:超大文档(>10MB)
- 10.3 反例3:字段名称大小写混乱
- 10.4 反例4:过度嵌套、多层嵌套
- 10.5 反例5:频繁更新、逐条更新
- 十一、企业级文档设计标准模板(可直接使用)
- 十二、总结
🌺The Begin🌺点点关注,收藏不迷路🌺 |
一、前言
在 Elasticsearch 中,文档(Document)是数据存储的最小单元,所有搜索、聚合、统计操作都基于文档展开。
文档设计是否合理,直接决定了:搜索性能、聚合速度、存储空间、集群稳定性、后期扩展性。
很多新手踩坑:数据写入慢、查询超时、聚合报错、字段冲突、无法扩展,本质都是文档设计不合理。
本文从设计原则、字段设计、结构设计、性能优化、安全规范等维度,全面讲解 ES 文档设计最佳实践,带流程图、序号、标准标题,可直接用于 CSDN 发布。
二、基础概念:什么是 ES 文档?
2.1 文档定义
- ES 中文档是JSON 格式的数据
- 相当于关系型数据库的一行数据
- 每个文档有唯一
_id - 文档受
mapping约束
2.2 文档核心特征
- 无固定结构(但生产必须固定)
- 层级嵌套、灵活
- 不支持事务、不支持关联 JOIN
- 偏向反规范化设计(冗余数据)
2.3 文档写入与查询流程图
三、Elasticsearch 文档设计 7 大核心原则
3.1 原则1:优先反规范化(冗余数据)
- ES不支持 JOIN
- 必须把关联数据冗余到同一个文档中
- 减少查询时的关联操作
- 用空间换性能
3.2 原则2:字段越少越好,避免过度嵌套
- 字段越少,检索越快、索引越小
- 不存储不需要搜索/聚合的字段
- 禁止无用字段、中间字段、临时字段
3.3 原则3:字段类型必须精准定义
- 禁止完全依赖动态映射
- 数字用数字类型、时间用 date 类型
- 文本必须区分
text和keyword
3.4 原则4:文档大小要适中
- 单个文档建议10KB~100KB
- 禁止超大文档(几MB)
- 大文档会导致写入慢、查询慢、内存溢出
3.5 原则5:禁止频繁修改文档
- ES 修改成本极高(标记删除+重写)
- 能批量写入就不逐条更新
- 日志类数据只写不改
3.6 原则6:结构扁平化,少用嵌套
- 嵌套对象
nested性能差 - 能扁平化就不要嵌套
3.7 原则7:提前规划,禁止字段冲突
- 同一个字段名称类型必须一致
- 禁止
user_id一会是文本,一会是数字
四、文档字段设计最佳实践(最重要章节)
4.1 文本字段必须使用 text + keyword 组合
"title":{"type":"text","analyzer":"ik_max_word","fields":{"keyword":{"type":"keyword","ignore_above":256}}}- text:用于全文检索
- keyword:用于排序、聚合、精准查询
4.2 精准匹配字段必须用 keyword
订单号、手机号、状态、枚举、ID、分类
"order_no": { "type": "keyword" }4.3 数字类型选择要合理
- 年龄 →
integer - 金额 →
double或scaled_float - 不要把数字存成 text
4.4 时间必须使用 date 类型
- 支持范围查询
- 支持时间聚合
"create_time": { "type": "date" }4.5 布尔类型用 boolean
- 禁用 0/1 存储
- 检索更快、空间更小
4.6 禁用不必要的字段属性
index: false:不需要搜索的字段doc_values: false:不需要排序聚合store: false:默认即可
4.7 统一字段命名规范
- 小写 + 下划线
- 禁止大小写混用:
userName/username会冲突 - 禁止特殊符号
五、文档结构设计最佳实践
5.1 优先扁平化结构(推荐)
{"id":1,"user_name":"张三","age":20,"product_name":"手机"}5.2 少用嵌套类型 nested
- nested 性能低
- 查询语法复杂
- 能不用就不用
5.3 少用对象嵌套
// 不推荐"user":{"name":"张三","info":{"age":20}}5.4 大文本字段单独存放
- 文章内容、日志详情
- 避免影响其他字段检索性能
六、文档大小与数量控制规范
6.1 最佳文档大小
10KB ~ 100KB
6.2 禁止超大文档
10MB 文档会严重影响节点稳定性、导致写入超时、频繁GC
6.3 大批量数据必须批量写入
- 批量写入:bulk
- 每批 500~1000 条
- 大小 5M~15M 最佳
七、避免动态映射陷阱(必看)
7.1 生产环境必须关闭动态映射
"dynamic":"strict"- 字段不匹配直接报错
- 避免自动创建错误字段
7.2 禁止 ES 自动生成字符串类型
- 会同时生成 text + keyword
- 导致索引体积暴增
- 必须手动定义
八、高可用与安全最佳实践
8.1 文档 ID 设计
- 不用自增 ID
- 使用业务 ID(如订单号、用户ID)
- 避免哈希倾斜
8.2 不存储原始不需要的字段
- 图片、视频、大文件不存入ES
- ES 只存索引和文本
8.3 敏感数据不存入ES
- 密码
- 密钥
- 隐私信息
九、高性能搜索最佳实践
9.1 只查询需要的字段_source
"_source":["id","title","price"]9.2 禁止*匹配所有字段
9.3 长文本字段禁用分词
十、文档设计反例(禁止使用)
10.1 反例1:所有字段都用 text
"user_id":{"type":"text"}// 错误10.2 反例2:超大文档(>10MB)
10.3 反例3:字段名称大小写混乱
10.4 反例4:过度嵌套、多层嵌套
10.5 反例5:频繁更新、逐条更新
十一、企业级文档设计标准模板(可直接使用)
PUT /product_index { "settings": { "number_of_shards": 3, "number_of_replicas": 1 }, "mappings": { "dynamic": "strict", "properties": { "id": { "type": "keyword" }, "title": { "type": "text", "analyzer": "ik_max_word", "fields": { "keyword": { "type": "keyword" } } }, "price": { "type": "double" }, "create_time": { "type": "date" }, "status": { "type": "keyword" } } } }十二、总结
- ES 文档设计核心:反规范化、冗余数据、扁平结构
- 字段必须精准定义类型,禁止动态映射
- 文本字段 text + keyword 组合是标准规范
- 文档大小控制在 10KB~100KB
- 少嵌套、少修改、少字段、高性能
- 严格遵循最佳实践,集群稳定、查询飞快
🌺The End🌺点点关注,收藏不迷路🌺 |