1. 为什么需要 Mapping?
(1) 核心原因
-
告诉 Elasticsearch 怎么处理数据:
比如,“这个字段是数字?还是文字?需要分词吗?”- 如果字段是“价格”,应该用数字类型(方便排序和计算)。
- 如果字段是“标题”,需要分词才能支持全文搜索(比如“小王子”会被拆分成“小”、“王”、“子”)。
-
避免自动推断的错误:
如果不指定 Mapping,Elasticsearch 会自动猜测字段类型,但可能不准确。- 比如,“123”可能是数字,也可能是字符串(比如订单号“ORD123”)。
(2) Mapping 包含哪些部分?
-
字段类型(Field Types)
text
:用于全文搜索(如文章内容)。keyword
:用于精确匹配(如分类名称)。integer
:整数类型(如年份)。date
:日期类型(如“2023-10-01”)。
-
字段参数(Field Parameters)
store
:是否存储原始值(默认不存储,节省空间)。index
:是否建立索引(不建立索引的字段无法搜索)。analyzer
:分词器(如中文分词用ik_max_word
)。
-
映射参数(Mapping Parameters)
dynamic
:是否自动添加新字段(默认允许)。dynamic_templates
:为未知字段设置默认类型。
(3) 使用场景
-
电商商品搜索:
title
字段用text
类型(支持“小王子”搜索)。price
字段用integer
类型(支持价格过滤)。category
字段用keyword
类型(精确匹配“小说”分类)。
-
日志分析:
timestamp
用date
类型(按时间排序)。error_message
用text
类型(支持模糊搜索错误原因)。
(4) 底层原理
Mapping 是 Elasticsearch 的“数据处理说明书”:
-
分词(Tokenization):
text
字段会被拆分成单词(如“小王子” →[小, 王, 子]
)。keyword
字段不会拆分(保持完整,如“小说” →["小说"]
)。
-
倒排索引构建:
- 根据字段类型,Elasticsearch 会为每个单词生成“文档列表”。
- 例如,搜索“小王子”会快速找到所有包含“小”、“王”、“子”的文档。
2. 流程图
以下是 Mapping 的作用流程:
+-------------------+
| 用户定义 Mapping | (指定字段类型)
+-------------------+
|
v
+-------------------+
| Elasticsearch | (根据 Mapping 处理数据)
| 服务器 |
+-------------------+
|
v
+-------------------+
| 分词和索引构建 | (如 text → 拆分单词,keyword → 保持原样)
+-------------------+
|
v
+-------------------+
| 返回搜索结果 | (基于 Mapping 的类型匹配)
+-------------------+
3. 概念图
以下是 Mapping 的核心概念:
+-------------------+
| Elasticsearch |
| Mapping |
+-------------------+
|
v
+-------------------+
| 字段类型 | (text、keyword、integer等)
+-------------------+
|
v
+-------------------+
| 字段参数 | (是否存储、是否分词)
+-------------------+
|
v
+-------------------+
| 动态映射 | (自动处理未知字段)
+-------------------+
4. UML 类图
以下是简化后的 UML 类图:
+-------------------+
| Index |
+-------------------+
| - mappings: Map | (所有字段的类型和参数)
+-------------------+
+-------------------+
| Field |
+-------------------+
| - type: string | (text、keyword等)
| - parameters: Map | (store、index等)
+-------------------+
5. 思维导图
以下是 Mapping 的思维导图:
+-------------------+
| Elasticsearch |
| Mapping |
+-------------------+
| + 核心功能 |
| + 定义字段类型 |
| + 控制分词 |
| + 高级设置 |
| + 存储原始值 |
| + 自动映射 |
+-------------------+
6. 实例代码(PHP 定义 Mapping)
以下是 PHP 代码示例,创建一个带有 Mapping 的索引:
<?php
// 1. 安装 Elasticsearch 客户端库(需要先执行:composer require elasticsearch)
require 'vendor/autoload.php';
// 2. 创建客户端连接到服务器
use Elasticsearch\ClientBuilder;
$client = ClientBuilder::create()
->setHosts(['http://localhost:9200'])
->build();
// 3. 定义索引的 Mapping(像给积木说明书)
$params = [
'index' => 'book_index', // 索引名称
'body' => [
'mappings' => [ // 映射定义
'properties' => [
'title' => ['type' => 'text'], // 文本类型,支持全文搜索
'author' => ['type' => 'keyword'], // 关键字类型,精确匹配
'year' => ['type' => 'integer'], // 整数类型,支持排序和计算
'price' => [
'type' => 'float', // 浮点数类型(如价格 19.99)
'store' => true // 存储原始值(查询时直接返回)
],
'tags' => [ // 数组类型
'type' => 'keyword', // 数组中的每个元素是关键字
'ignore_above' => 20 // 忽略超过20个字符的标签
]
]
]
]
];
// 4. 创建索引
$response = $client->indices()->create($params);
print_r($response); // 输出结果,确认创建成功
// 5. 插入文档测试
$client->index([
'index' => 'book_index',
'id' => '1',
'body' => [
'title' => '小王子',
'author' => '圣埃克苏佩里',
'year' => 1943,
'price' => 29.99,
'tags' => ['童话', '经典']
]
]);
// 6. 查询测试(验证 Mapping 的效果)
$searchParams = [
'index' => 'book_index',
'body' => [
'query' => [
'bool' => [
'must' => [
['match' => ['title' => '王子']], // 搜索包含“王子”的书(text字段支持分词)
['term' => ['tags' => '童话']] // 精确匹配标签“童话”(keyword类型)
]
]
]
]
];
$searchResult = $client->search($searchParams);
print_r($searchResult);
代码注释详细解释
第 3 步:定义 Mapping
'title' => ['type' => 'text'],
- 作用:将
title
字段定义为text
类型,支持全文搜索。 - 为什么这么写:
text
类型会自动分词(如“小王子” → “小”、“王”、“子”),方便模糊匹配。 - 知识点:Elasticsearch 的 字段类型。
'author' => ['type' => 'keyword'],
- 作用:将
author
字段定义为keyword
类型,用于精确匹配。 - 为什么这么写:作者名称需要精确查找(如“圣埃克苏佩里”必须完全匹配)。
- 知识点:
keyword
类型的不可分词特性。
'price' => ['type' => 'float', 'store' => true],
- 作用:定义
price
为浮点数,并存储原始值。 - 为什么这么写:
store
为true
时,查询结果会直接返回原始价格值。 - 知识点:字段的
store
参数。
第 6 步:查询测试
'match' => ['title' => '王子']
- 作用:搜索
title
中包含“王子”(分词后的“王”或“子”均可匹配)。 - 为什么这么写:
text
字段已分词,支持模糊搜索。 - 知识点:
match
查询的全文搜索特性。
'term' => ['tags' => '童话']
- 作用:精确匹配
tags
中的“童话”标签。 - 为什么这么写:
tags
是keyword
类型,term
查询精确匹配。 - 知识点:
term
查询与keyword
类型的配合。
7. 总结
- Mapping 是数据的“说明书”:告诉 Elasticsearch 如何存储和搜索每个字段。
- 核心功能:定义字段类型、控制分词、优化查询性能。
- 底层原理:通过 Mapping 指导分词和倒排索引的构建,实现高效搜索。