字段类型怎么选
text 会分词、支持全文检索,但默认不能用于排序与聚合;keyword 保留整个字符串,适合精确过滤、排序与聚合。字符串字段经常同时需要两种能力,于是用 multi-field 在同一字段下挂一个 keyword 子字段兼顾。类型一旦在映射中确定就不能修改,选型要在建索引前想清楚。
基本信息
| text | 分词索引,用于全文检索;排序聚合需开启 fielddata(耗内存) |
|---|---|
| keyword | 整串匹配、term 查询、排序与聚合;默认不分词 |
| 数值类型 | long / integer / short / byte / double / float / scaled_float |
| 日期与布尔 | date(含多种 format)、boolean |
| 特殊类型 | ip / geo_point / object / nested / dense_vector |
| multi-field | 同一字段挂多个子类型,如 city 与 city.raw |
典型使用场景
- 商品标题、文章正文用 text 支持分词检索
- 状态、标签、用户 ID 用 keyword 做精确过滤与聚合
- 需要在同一字段上既检索又聚合时用 multi-field
- 时间字段用 date 并显式声明 format,避免被推断成 text
- IP 与坐标用专用类型,普通字符串无法做范围与距离查询
- 对象数组需要成组匹配时用 nested 而不是普通 object
multi-field 示例
multi-field 示例
{
"properties": {
"city": {
"type": "text",
"fields": {
"raw": { "type": "keyword", "ignore_above": 256 }
}
},
"status": { "type": "keyword" },
"created_at": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss||epoch_millis" }
}
}类型能力对照
| 类型 | 全文检索 | 排序聚合 | 典型字段 |
|---|---|---|---|
| text | 支持(分词) | 默认不支持 | 标题、正文、描述 |
| keyword | 不支持分词 | 支持 | 状态、标签、ID |
| integer/long | 不适用 | 支持 | 数量、计数 |
| date | 不适用 | 支持 | 时间戳、创建时间 |
| ip | 不适用 | 支持(含网段) | 客户端地址 |
| nested | 需 nested 查询 | 有限制 | 订单明细、地址列表 |
对 text 字段直接做 terms 聚合会报 fielddata is disabled;应改用 city.raw 这类 keyword 子字段,或在查询期用运行时字段转换。
keyword 子字段通常设置 ignore_above(常见 256),超长值不会被索引也进不了聚合结果,长文本不适合当 keyword。
数字被存成字符串(或字符串数字存成数值)会导致范围查询与聚合语义错位,写入前用一致的类型;类型不符时可考虑写入管道转换。
scaled_float 用缩放因子把小数存成整数,适合金额类字段兼顾精度与存储;货币金额常用分或万分位整数存储。
类型选型决策顺序
- 先明确字段用途:全文检索、精确过滤,还是排序聚合
- 既要检索又要聚合的字符串用 multi-field:主字段 text 加 keyword 子字段
- 只做精确匹配与聚合的字符串直接设 keyword,省掉分词开销
- 数量与金额避免用字符串存储,范围查询与聚合都依赖数值类型
- 时间字段显式声明 date 与 format,不要依赖自动映射推断
- 数组对象需要成组条件匹配时用 nested,普通 object 会跨元素串位
不同字段的查询方式
不同字段的查询方式
GET /my-index/_search
{ "query": { "match": { "title": "蓝莓 果酱" } } } # text:先分词
GET /my-index/_search
{ "query": { "term": { "status": "paid" } } } # keyword:整串匹配
GET /my-index/_search
{ "size": 0, "aggs": { "by_city": { "terms": { "field": "city.raw" } } } } # 聚合走 keyword 子字段字段类型属于映射的一部分,只能新增不能修改;给未来可能要聚合的字段预留 keyword 子字段,成本远低于事后重建索引。
自动映射对字符串的处理通常是 text 加 keyword 子字段,所以默认还能聚合;但显式声明为 text 之后就不会再有子字段,行为差异要记清。
对象数组若声明成普通 object,索引时会被扁平化,条件可能分别命中不同元素;只有 nested 才能保证同一元素内的字段成组匹配。
常用类型速查
- 短枚举值如状态、类型、渠道:keyword
- 名称与地址等需要模糊搜索的文本:text 加 keyword 子字段
- 数量、计数、库存:integer 或 long
- 价格与金额:scaled_float,或按分存储的整型
- 时间点:date 并显式声明 format
- IP 地址:ip 类型,可做网段范围查询
把字符串当作数值类型字段的查询值通常无命中,类型一致性是排查「有数据却查不到」的第一检查项。