Appearance
映射基础
什么是映射?
映射(Mapping) 用来定义索引中字段的类型与行为,例如:是否分词、是否存储、用什么分析器等。可以类比为关系型数据库的表结构(Schema)。映射一旦确定,已存在字段的类型不能修改,只能通过 Reindex 迁移到新索引。
动态映射(Dynamic Mapping)
若不显式指定 mapping,在首次写入文档时,Elasticsearch 会根据 JSON 值的类型自动推断字段类型并创建映射,这就是动态映射。
常见对应关系:
| JSON 类型 | 推断的 ES 类型 |
|---|---|
字符串 "hello" | text(并带 keyword 子字段,因版本而异) |
整数 42 | long |
小数 3.14 | float 或 double |
布尔 true/false | boolean |
| 日期字符串(如 ISO8601) | 可能被识别为 date |
对象 {} | object |
| 数组 | 由数组元素类型决定 |
动态映射的优点是上手快、灵活;缺点是可能推断出不符合预期的类型(例如希望某字段做精确匹配却被当成 text),生产环境建议对关键索引使用显式映射。
显式映射(Explicit Mapping)
在创建索引时通过 mappings 指定各字段类型:
http
PUT /books
{
"settings": { "number_of_shards": 1, "number_of_replicas": 0 },
"mappings": {
"properties": {
"title": { "type": "text" },
"author": { "type": "keyword" },
"year": { "type": "integer" },
"price": { "type": "float" },
"on_sale": { "type": "boolean" },
"publish_date": { "type": "date" }
}
}
}常用类型一览:
| 类型 | 说明 |
|---|---|
| text | 全文检索,会分词,不用于排序/聚合(通常用子字段 keyword) |
| keyword | 不分词,精确匹配、排序、聚合 |
| long / integer / short | 整数 |
| float / double | 浮点数 |
| date | 日期,可指定 format |
| boolean | 布尔 |
| object | 嵌套对象,子字段在 properties 下 |
| nested | 嵌套数组(每个元素独立存储,便于嵌套查询) |
| ip | IPv4/IPv6 |
| geo_point | 经纬度 |
text 与 keyword 的区别(新手必考)
- text:会对内容分词,用于全文检索(match 等)。默认不用于排序、聚合(因为按词存)。
- keyword:不分词,把整段字符串当作一个整体,用于精确匹配(term/terms)、排序、聚合。
例如:"title": "Elasticsearch 教程"
- 若
title为 text:可能被分成elasticsearch、教程等词,用 match 搜“教程”能命中。 - 若
title为 keyword:只有完整匹配"Elasticsearch 教程"才能命中。
多字段:同时支持全文与精确
同一字段常需要“可搜索”又“可聚合/排序”,可用 fields 同时保留 text 与 keyword:
http
PUT /products
{
"mappings": {
"properties": {
"name": {
"type": "text",
"fields": {
"keyword": { "type": "keyword" }
}
}
}
}
}- 搜索用:
name(text)。 - 排序/聚合/精确匹配用:
name.keyword(keyword)。
映射的查看与修改
- 查看:
GET /索引名/_mapping。 - 修改:已存在字段的 type 不能改;只能新增字段,或通过 Reindex 把数据迁到带新 mapping 的索引(见 常用运维操作)。
索引模板(Index Template)
索引模板可以在创建新索引时自动套用相同的 settings 和 mappings,适合按时间滚动的索引(如按天建的日志索引)。
示例:匹配 logs-* 的索引都使用同一模板:
http
PUT _index_template/logs_template
{
"index_patterns": ["logs-*"],
"template": {
"settings": { "number_of_shards": 1, "number_of_replicas": 0 },
"mappings": {
"properties": {
"message": { "type": "text" },
"level": { "type": "keyword" },
"@timestamp": { "type": "date" }
}
}
}
}之后创建 logs-2024-01-01 等索引时,会自动应用上述配置。多个模板命中同一索引时,按优先级合并(priority 高的覆盖低的)。