1. ES数据建模基础:什么是数据建模、ES中的数据类型概览、字段类型选择原则

大家好,欢迎来到这门实战课。

今天咱们聊聊数据建模。嗯,这词听起来挺唬人的。说白了,就是决定你的数据长什么样、怎么存、怎么查。我见过太多团队,上来就咔咔往ES里灌数据,结果查询慢得像蜗牛,才发现字段类型全用错了。所以,这一章咱们把地基打牢。

1.1 什么是数据建模?

数据建模,就是设计数据的结构、关系和约束。在ES里,它特指三件事:

  • 定义索引的映射(Mapping)——每个字段叫什么、是什么类型
  • 设计文档结构——是扁平化还是嵌套?用对象还是数组?
  • 规划索引策略——一个索引还是多个?按时间分还是按业务分?

我个人习惯把数据建模比作盖房子。映射就是地基,地基歪了,后面装修再漂亮也白搭。我在项目中遇到过一家电商公司,把商品价格存成了字符串。结果做范围查询时,ES按字典序比较,"9.99"比"100.00"大。你说这坑不坑?

核心观点:ES的数据建模,本质上是为搜索和分析服务的。它不像关系型数据库那样强调范式,而是更关注查询效率。

1.2 ES中的数据类型概览

ES的数据类型,我习惯分成三大类。你想想看,就像工具箱里的扳手、螺丝刀和电钻,各有各的用处。

1.2.1 核心类型

类型 说明 常见场景
text 全文检索字段,会被分词 文章标题、商品描述
keyword 精确值字段,不分词 订单号、邮箱、标签
long / integer 整数类型 年龄、数量、ID
double / float 浮点数类型 价格、评分
boolean 布尔类型 是否上架、是否删除
date 日期类型 创建时间、更新时间

1.2.2 复杂类型

  • object:默认的JSON对象类型。ES会把内部字段扁平化处理。
  • nested:嵌套对象。解决了object类型下数组查询的「扁平化陷阱」。
  • flattened:将整个对象当作一个keyword处理。适合字段名不确定的场景。

1.2.3 特殊类型

  • geo_point:经纬度坐标。支持距离排序、范围查询。
  • ip:IP地址。支持CIDR匹配。
  • join:父子关系。用于一对多关联查询。
  • alias:字段别名。不占存储,只做查询路由。

我的小技巧:拿不准用什么类型时,先问自己三个问题——这个字段要全文搜索吗?要排序吗?要聚合统计吗?答案决定了80%的类型选择。

1.3 字段类型选择原则

这部分是我踩坑踩出来的经验。我曾经因为选错类型,导致一个日志索引的存储膨胀了3倍,查询慢了5倍。嗯,这里要注意,原则就那么几条,但每一条背后都是血泪史。

原则一:能用keyword就别用text

为什么?因为text会分词,会建倒排索引,占空间、耗性能。如果你只需要精确匹配、排序或聚合,keyword是更好的选择。

// 错误示范:把订单号设为text
"order_id": { "type": "text" }

// 正确做法:设为keyword
"order_id": { "type": "keyword" }

原则二:能用整数就别用字符串

ES对数值类型的压缩和索引效率远高于字符串。我在项目中遇到过有人把年龄存成"18岁"这种字符串,结果想统计平均年龄时,只能写脚本提取数字。何必呢?

原则三:日期一定要用date类型

很多人习惯把时间存成字符串,比如"2024-01-15 10:30:00"。但这样你就没法做日期范围聚合、时区转换、日期数学运算了。记住,ES的date类型支持多种格式,包括时间戳。

// 推荐写法
"create_time": {
  "type": "date",
  "format": "yyyy-MM-dd HH:mm:ss||epoch_millis"
}

原则四:避免使用过于宽泛的类型

比如所有数字都用double。double占8字节,integer只占4字节。数据量上亿时,这个差距就是几十GB。能用integer别用long,能用float别用double。

原则五:谨慎使用nested类型

nested查询性能比object差很多,因为每个嵌套对象都是独立的Lucene文档。我建议:如果只是展示,用object就够了;只有需要独立查询子对象时,才用nested。

避坑指南:我曾经接手过一个项目,把用户的所有标签都存成了text类型。结果做标签去重统计时,ES返回的是分词后的词条,根本不是原始标签。最后只能重建索引,花了整整一个周末。所以,字段类型一定要在索引创建前想清楚。

1.4 小结

这一章咱们聊了数据建模的本质、ES的数据类型家族,以及字段选择的五条黄金原则。说白了,数据建模就是「存什么、怎么存、查得快」。下一章,我会带你实战一个完整的电商搜索模型,从需求分析到映射设计,一步步走一遍。

记住一句话:好的数据建模,能让你的ES集群跑得又快又稳;差的数据建模,能让你天天加班修数据。