Elasticsearch映射管理 #
一、映射概述 #
1.1 什么是映射 #
映射定义了文档如何存储和索引,包括:
- 字段的数据类型
- 字段如何被索引
- 字段如何被搜索
text
映射作用
├── 数据类型定义
│ └── 确定字段存储格式
├── 索引配置
│ └── 是否索引、如何分词
├── 搜索配置
│ └── 如何搜索、如何排序
└── 存储优化
└── 压缩、存储策略
1.2 映射类型 #
| 类型 | 说明 |
|---|---|
| 动态映射 | 自动检测字段类型 |
| 显式映射 | 手动定义字段类型 |
二、动态映射 #
2.1 动态映射规则 #
Elasticsearch自动检测并添加字段:
json
PUT /products/_doc/1
{
"name": "iPhone 15",
"price": 999,
"in_stock": true,
"tags": ["phone", "apple"]
}
自动生成的映射:
json
{
"products": {
"mappings": {
"properties": {
"name": { "type": "text", "fields": { "keyword": { "type": "keyword" } } },
"price": { "type": "long" },
"in_stock": { "type": "boolean" },
"tags": { "type": "text", "fields": { "keyword": { "type": "keyword" } } }
}
}
}
}
2.2 类型推断规则 #
| JSON值 | Elasticsearch类型 |
|---|---|
| null | 不添加字段 |
| true/false | boolean |
| 整数 | long |
| 浮点数 | float |
| 字符串 | text + keyword |
| 数组 | 取决于第一个非空元素 |
| 对象 | object |
2.3 动态映射配置 #
bash
PUT /products
{
"mappings": {
"dynamic": "true",
"properties": {
"name": { "type": "text" }
}
}
}
dynamic参数值:
| 值 | 说明 |
|---|---|
| true | 自动添加新字段(默认) |
| false | 新字段不索引但存在于_source |
| strict | 遇到新字段报错 |
| runtime | 新字段作为运行时字段 |
2.4 动态模板 #
bash
PUT /products
{
"mappings": {
"dynamic_templates": [
{
"strings_as_keyword": {
"match_mapping_type": "string",
"match": "*_code",
"mapping": {
"type": "keyword"
}
}
},
{
"strings_as_text": {
"match_mapping_type": "string",
"mapping": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
},
{
"longs_as_integer": {
"match_mapping_type": "long",
"mapping": {
"type": "integer"
}
}
}
]
}
}
2.5 动态模板匹配规则 #
| 参数 | 说明 |
|---|---|
| match | 匹配字段名 |
| unmatch | 排除字段名 |
| match_mapping_type | 匹配数据类型 |
| path_match | 匹配字段路径 |
| path_unmatch | 排除字段路径 |
示例:
bash
PUT /logs
{
"mappings": {
"dynamic_templates": [
{
"message_field": {
"match_mapping_type": "string",
"path_match": "message.*",
"mapping": {
"type": "text"
}
}
},
{
"status_codes": {
"match": "status_*",
"mapping": {
"type": "keyword"
}
}
}
]
}
}
三、显式映射 #
3.1 创建索引时定义映射 #
bash
PUT /products
{
"mappings": {
"properties": {
"name": {
"type": "text",
"analyzer": "standard"
},
"description": {
"type": "text",
"analyzer": "standard"
},
"price": {
"type": "scaled_float",
"scaling_factor": 100
},
"brand": {
"type": "keyword"
},
"category": {
"type": "keyword"
},
"tags": {
"type": "keyword"
},
"in_stock": {
"type": "boolean"
},
"created_at": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"location": {
"type": "geo_point"
}
}
}
}
3.2 添加新字段 #
bash
PUT /products/_mapping
{
"properties": {
"rating": {
"type": "float"
},
"reviews": {
"type": "integer"
}
}
}
3.3 查看映射 #
bash
GET /products/_mapping
3.4 查看特定字段映射 #
bash
GET /products/_mapping/field/name
GET /products/_mapping/field/name,price
四、字段属性配置 #
4.1 通用属性 #
json
{
"properties": {
"field_name": {
"type": "text",
"index": true,
"doc_values": true,
"store": false,
"enabled": true,
"null_value": "NULL",
"ignore_above": 256
}
}
}
| 属性 | 说明 | 默认值 |
|---|---|---|
| type | 字段类型 | - |
| index | 是否索引 | true |
| doc_values | 是否存储doc_values | true |
| store | 是否单独存储 | false |
| enabled | 是否处理字段 | true |
| null_value | 空值替换 | - |
| ignore_above | 超过长度不索引 | - |
4.2 text字段属性 #
json
{
"properties": {
"content": {
"type": "text",
"analyzer": "standard",
"search_analyzer": "standard",
"fielddata": false,
"index": true,
"norms": true,
"index_options": "positions",
"term_vector": "no"
}
}
}
| 属性 | 说明 | 默认值 |
|---|---|---|
| analyzer | 索引分析器 | standard |
| search_analyzer | 搜索分析器 | 同analyzer |
| fielddata | 是否启用fielddata | false |
| norms | 是否存储规范 | true |
| index_options | 索引选项 | positions |
4.3 keyword字段属性 #
json
{
"properties": {
"status": {
"type": "keyword",
"ignore_above": 256,
"index": true,
"doc_values": true,
"normalizer": "lowercase"
}
}
}
4.4 数值字段属性 #
json
{
"properties": {
"price": {
"type": "scaled_float",
"scaling_factor": 100,
"coerce": true,
"ignore_malformed": false
}
}
}
4.5 日期字段属性 #
json
{
"properties": {
"created_at": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||epoch_millis",
"locale": "zh_CN",
"ignore_malformed": false
}
}
}
五、多字段(Multi-fields) #
5.1 基本用法 #
json
{
"properties": {
"title": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
},
"english": {
"type": "text",
"analyzer": "english"
}
}
}
}
}
5.2 使用方式 #
bash
GET /products/_search
{
"query": {
"match": {
"title": "iPhone"
}
}
}
GET /products/_search
{
"query": {
"term": {
"title.keyword": "iPhone 15 Pro"
}
}
}
GET /products/_search
{
"query": {
"match": {
"title.english": "phones"
}
}
}
六、嵌套对象映射 #
6.1 object类型 #
json
{
"properties": {
"user": {
"type": "object",
"properties": {
"name": { "type": "text" },
"email": { "type": "keyword" },
"address": {
"type": "object",
"properties": {
"city": { "type": "keyword" },
"street": { "type": "text" }
}
}
}
}
}
}
6.2 nested类型 #
json
{
"properties": {
"comments": {
"type": "nested",
"properties": {
"user": { "type": "keyword" },
"message": { "type": "text" },
"created_at": { "type": "date" }
}
}
}
}
6.3 nested查询 #
bash
GET /posts/_search
{
"query": {
"nested": {
"path": "comments",
"query": {
"bool": {
"must": [
{ "term": { "comments.user": "alice" } },
{ "match": { "comments.message": "great" } }
]
}
},
"inner_hits": {}
}
}
}
七、运行时字段 #
7.1 定义运行时字段 #
bash
PUT /products
{
"mappings": {
"runtime": {
"price_with_tax": {
"type": "double",
"script": {
"source": "emit(doc['price'].value * 1.1)"
}
}
},
"properties": {
"name": { "type": "text" },
"price": { "type": "double" }
}
}
}
7.2 查询时定义运行时字段 #
bash
GET /products/_search
{
"runtime_mappings": {
"price_with_tax": {
"type": "double",
"script": {
"source": "emit(doc['price'].value * 1.1)"
}
}
},
"query": {
"range": {
"price_with_tax": {
"lte": 1000
}
}
}
}
7.3 运行时字段特点 #
text
运行时字段
├── 优点
│ ├── 不增加索引大小
│ ├── 灵活,可随时修改
│ └── 不需要重建索引
└── 缺点
├── 查询性能较低
└── 不能用于排序和聚合优化
八、元数据字段 #
8.1 _source字段 #
json
{
"mappings": {
"_source": {
"enabled": true,
"excludes": ["sensitive_data"],
"includes": ["*"]
}
}
}
8.2 _routing字段 #
json
{
"mappings": {
"_routing": {
"required": true
}
}
}
8.3 _index字段 #
bash
GET /_search
{
"query": {
"term": {
"_index": "products"
}
}
}
九、映射限制 #
9.1 字段数量限制 #
bash
PUT /products/_settings
{
"index.mapping.total_fields.limit": 2000
}
9.2 字段深度限制 #
bash
PUT /products/_settings
{
"index.mapping.depth.limit": 20
}
9.3 嵌套字段限制 #
bash
PUT /products/_settings
{
"index.mapping.nested_fields.limit": 50,
"index.mapping.nested_objects.limit": 10000
}
十、映射更新策略 #
10.1 添加字段 #
bash
PUT /products/_mapping
{
"properties": {
"new_field": {
"type": "keyword"
}
}
}
10.2 修改字段类型 #
已存在的字段类型不能直接修改,需要重建索引:
bash
PUT /products_v2
{
"mappings": {
"properties": {
"name": { "type": "keyword" }
}
}
}
POST /_reindex
{
"source": { "index": "products" },
"dest": { "index": "products_v2" }
}
POST /_aliases
{
"actions": [
{ "remove": { "index": "products", "alias": "products" } },
{ "add": { "index": "products_v2", "alias": "products" } }
]
}
10.3 使用索引别名切换 #
bash
POST /_aliases
{
"actions": [
{ "remove": { "index": "products_v1", "alias": "products" } },
{ "add": { "index": "products_v2", "alias": "products" } }
]
}
十一、映射最佳实践 #
11.1 设计原则 #
text
映射设计原则
├── 明确字段类型
│ └── 不要依赖动态映射
├── 合理使用multi-fields
│ └── 同一字段多种用途
├── 控制字段数量
│ └── 避免字段爆炸
├── 使用nested处理数组对象
│ └── 保证查询准确性
└── 合理配置index选项
└── 不搜索的字段不索引
11.2 性能优化 #
json
{
"properties": {
"content": {
"type": "text",
"norms": false,
"index_options": "freqs"
},
"status": {
"type": "keyword",
"doc_values": true,
"index": false
}
}
}
11.3 存储优化 #
json
{
"mappings": {
"_source": {
"excludes": ["large_field"]
},
"properties": {
"large_field": {
"type": "text",
"store": false
}
}
}
}
十二、总结 #
本章介绍了Elasticsearch映射管理:
- 动态映射自动推断字段类型
- 显式映射提供精确控制
- 动态模板实现灵活的类型映射
- multi-fields实现一字段多用途
- nested解决对象数组独立性问题
- 运行时字段提供灵活的计算能力
下一步,我们将学习文档索引操作。
最后更新:2026-03-27