Elasticsearch映射:优化搜索性能的关键
是的,在 Elasticsearch 中可以并且强烈建议显式定义映射(Mapping)。映射定义了索引中的文档如何存储和索引,包括字段的数据类型(如 text
, keyword
, date
, integer
等)及其相关属性(如分词器、是否索引、格式等)。
🔑 为什么需要定义映射?
- 控制数据类型:防止 Elasticsearch 自动推断错误(如将数字识别为字符串)。
- 优化性能:合理设置字段类型(如
keyword
适合精确匹配,text
适合全文搜索)。 - 节省存储:禁用不需要索引的字段。
- 高级控制:自定义分词器、多字段(
fields
)等。
✏️ 如何定义映射?
1️⃣ 创建索引时定义映射
PUT /my_index
{"mappings": {"properties": { "title": { "type": "text" }, "category": { "type": "keyword" },"price": { "type": "float" },"created_at": { "type": "date","format": "yyyy-MM-dd HH:mm:ss"},"tags": { "type": "keyword" },"description": { "type": "text","index": false // 不参与搜索,仅存储}}}
}
2️⃣ 向已有索引添加新字段映射
PUT /my_index/_mapping
{"properties": {"new_field": { "type": "integer" }}
}
️ 注意:已存在的字段映射无法修改(除非使用 Reindex API 重建索引)。
🔧 常用映射参数
参数 | 说明 | 示例 |
---|---|---|
type | 字段类型(text , keyword , long , boolean , nested 等) | "type": "date" |
index | 是否索引(true /false ) | "index": false |
format | 自定义日期格式 | "format": "yyyy-MM-dd" |
fields | 为字段定义多子字段 | 见下方👇 |
analyzer | 指定分词器(如 standard , ik_smart ) | "analyzer": "ik_max_word" |
ignore_above | 忽略超过长度的 keyword 字段 | "ignore_above": 256 |
🌟 多字段(Multi-fields)示例
一个字段同时支持全文搜索和精确聚合:
{"product_name": {"type": "text", // 全文搜索"fields": {"raw": { // 子字段名"type": "keyword" // 精确匹配/聚合}}}
}
- 使用全文搜索:
product_name: "手机"
- 使用精确聚合:
product_name.raw: "iPhone 15 Pro"
动态映射 vs 显式映射
动态映射(Dynamic) | 显式映射(Explicit) |
---|---|
ES 自动推断字段类型 | 手动预定义字段类型 |
灵活但有风险(类型错误) | 安全可控,性能更优 |
适合快速原型 | 生产环境必备 |
可通过 dynamic
参数控制动态规则:
"mappings": {"dynamic": "strict", // 禁止自动新增字段"properties": {...}
}
💡 最佳实践
- 提前规划映射:索引创建前设计好字段类型。
- 慎用动态映射:生产环境建议设为
strict
或runtime
。 - 善用
keyword
:精确查询/聚合的字段勿用text
。 - 定期检查映射:使用
GET /my_index/_mapping
验证。
📌 提示:遇到无法修改映射的情况?用 Reindex API 将数据迁移到新索引!