Elasticsearch到底为什么需要Mapping的字段类型一共包含哪些部分?使用场景是什么?底层原理是什么?_esmapping的字段类型
1. 为什么需要 Mapping
的字段类型?
核心比喻:像“图书分类标签”一样管理数据
- 问题:
如果图书馆的书没有分类标签(如“故事书”“工具书”),管理员无法快速找到你想借的书。
类似地,Elasticsearch 需要知道字段类型(如“数字”“日期”“文本”),才能正确存储和搜索数据。 - 解决办法:
字段类型告诉 Elasticsearch 如何处理数据(如是否分词、如何存储、如何计算)。 - 核心目的:
确保数据存储高效、查询准确、支持复杂操作(如计算销售额、统计日期)。
2. 字段类型包含哪些部分?
核心组成部分
- 基础类型
text
:支持全文搜索(如文章内容)。keyword
:精确匹配(如分类、ID)。integer
:数值计算(如价格、数量)。date
:时间操作(如订单日期)。boolean
:布尔值(如是否已发货)。
- 参数设置
store
:是否存储原始值(节省空间)。index
:是否建立索引(不索引的字段无法搜索)。ignore_above
:超过多少字符不索引(如20
表示超过20字符的字段不索引)。
- 高级类型
object
:存储复杂对象(如用户地址)。nested
:嵌套对象(如评论列表)。geo_point
:地理位置(如经纬度)。
3. 使用场景
- 全文搜索:用
text
类型查询商品标题(如“手机”)。 - 精确匹配:用
keyword
类型查找分类(如“小说”)。 - 数值计算:用
integer
类型统计总销售额或过滤价格范围。 - 时间分析:用
date
类型统计“过去一周”的订单。 - 复杂结构:用
object
存储用户地址或嵌套评论。
4. 底层原理
(1) 字段类型如何影响数据处理
- 存储:
text
:分词后存储词项(如“小王子” →[小, 王, 子]
)。keyword
:存储完整值(如“小说” →[\"小说\"]
)。date
:转为时间戳(如2023-10-01
→1696118400
)。
- 索引构建:
- 根据类型建立不同的索引(如
text
建立倒排索引,date
建立时间戳索引)。
- 根据类型建立不同的索引(如
- 查询优化:
integer
支持范围查询(如price > 50
),text
支持模糊搜索。
(2) 核心机制
- 分词器:
text
类型会拆分文本,而keyword
不拆分。 - 索引结构:
text
→ 倒排索引(记录词项到文档的映射)。date
→ 时间戳索引(支持时间范围查询)。
- 类型约束:
确保数据类型正确(如插入字符串到integer
字段会报错)。
5. 流程图
以下是字段类型工作的流程:
+-------------------+| 用户定义字段类型 | (如 \"price\" 是 integer)+-------------------+ | v+-------------------+| Elasticsearch || 根据类型处理数据 || 1. 分词(text) || 2. 存储数值(integer)|| 3. 转换时间(date)|+-------------------+ | v+-------------------+| 构建索引 | (根据类型建立不同索引)+-------------------+ | v+-------------------+| 用户查询 | (如 \"价格>50\")+-------------------+ | v+-------------------+| 根据类型匹配数据 | (integer 类型直接比较数值)+-------------------+
6. 概念图
以下是字段类型的核心概念:
+-------------------+| 字段类型 |+-------------------+ | v+-------------------+| 文本类型(text) | (分词,支持模糊搜索)+-------------------+ | v+-------------------+| 关键字类型(keyword)| (精确匹配,不拆分)+-------------------+ | v+-------------------+| 数值类型(integer)| (数值计算,范围查询)+-------------------+ | v+-------------------+| 日期类型(date) | (时间戳转换,按周/日统计)+-------------------+
7. UML 类图
以下是简化后的 UML 类图:
+-------------------+| FieldMapping |+-------------------+| - type: string | (字段类型,如 text/integer)| - settings: object| (参数,如分词器、存储选项)+-------------------++-------------------+| TextField |+-------------------+| - analyzer: string| (分词器,如 standard)| - index: bool | (是否建立索引)+-------------------++-------------------+| IntegerField |+-------------------+| - coerce: bool | (自动转换单位)+-------------------++-------------------+| DateField |+-------------------+| - format: string | (日期格式,如 yyyy-MM-dd)+-------------------+
8. 思维导图
以下是字段类型的思维导图:
+-------------------+| 字段类型 |+-------------------+| + 核心类型 || + text || + keyword || + integer || + date || + 高级类型 || + object || + geo_point || + 参数设置 || + 分词器 || + 存储选项 || + 作用 || + 存储优化 || + 查询加速 |+-------------------+
9. 实例代码(PHP 演示字段类型)
以下是 PHP 代码示例,创建包含多种字段类型的索引并测试查询:
<?php// 1. 安装 Elasticsearch 客户端库(需要先执行:composer require elasticsearch)require \'vendor/autoload.php\';// 2. 创建客户端连接到服务器use Elasticsearch\\ClientBuilder;$client = ClientBuilder::create() ->setHosts([\'http://localhost:9200\']) ->build();// 3. 创建索引并定义多种字段类型$params = [ \'index\' => \'product_index\', \'body\' => [ \'mappings\' => [ \'properties\' => [ \'title\' => [\'type\' => \'text\'], // 1. 文本类型,支持模糊搜索 \'category\' => [\'type\' => \'keyword\'], // 2. 关键字类型,精确匹配 \'price\' => [\'type\' => \'integer\'], // 3. 数值类型,支持计算 \'created_at\' => [\'type\' => \'date\', \'format\' => \'yyyy-MM-dd\'], // 4. 日期类型,格式化存储 \'is_available\' => [\'type\' => \'boolean\'] // 5. 布尔类型,存储 true/false ] ] ]];$client->indices()->create($params); // 创建索引// 4. 插入测试数据$client->index([ \'index\' => \'product_index\', \'id\' => \'1\', \'body\' => [ \'title\' => \'小王子与玫瑰\', \'category\' => \'小说\', \'price\' => 99, \'created_at\' => \'2023-10-01\', \'is_available\' => true ]]);// 5. 多类型查询测试$searchParams = [ \'index\' => \'product_index\', \'body\' => [ \'query\' => [ \'bool\' => [ \'must\' => [ [\'match\' => [\'title\' => \'玫瑰\']], // 6. text 类型的模糊搜索 [\'term\' => [\'category\' => \'小说\']], // 7. keyword 类型的精确匹配 [\'range\' => [\'price\' => [\'gt\' => 50]]], // 8. integer 类型的范围查询 [\'term\' => [\'is_available\' => true]] // 9. boolean 类型的条件过滤 ] ] ], \'aggs\' => [ // 10. 聚合统计 \'weekly_sales\' => [ \'date_histogram\' => [ \'field\' => \'created_at\', \'calendar_interval\' => \'week\', \'format\' => \'yyyy-ww\' ] ] ] ]];// 6. 执行查询并输出结果$searchResult = $client->search($searchParams);print_r($searchResult);// 7. 清理$client->indices()->delete([\'index\' => \'product_index\']);
代码注释详细解释
第 3 步:定义字段类型
\'category\' => [\'type\' => \'keyword\']
- 作用:将
category
字段定义为keyword
类型,确保精确匹配。 - 为什么这么写:分类需要完全匹配(如“小说” ≠ “小说家”)。
- 知识点:
keyword
类型不分词,支持精确查询。
第 5 步:布尔类型
\'is_available\' => [\'type\' => \'boolean\']
- 作用:定义布尔类型字段,存储“是否可用”状态。
- 为什么这么写:需要存储
true/false
值,如商品是否上架。 - 知识点:布尔类型用于二进制条件判断。
第 6 步:多类型查询
\'match\' => [\'title\' => \'玫瑰\']
- 作用:模糊搜索
title
中包含“玫瑰”的文档(分词后匹配)。 - 为什么这么写:
text
类型支持分词和模糊搜索。 - 知识点:
match
查询与text
类型的配合。
第 6 步:范围查询
\'range\' => [\'price\' => [\'gt\' => 50]]
- 作用:查找
price
大于50
的商品。 - 为什么这么写:
integer
类型支持数值比较。 - 知识点:
range
查询用于数值范围。
第 6 步:日期聚合
\'calendar_interval\' => \'week\'
- 作用:按周统计
created_at
字段的时间分布。 - 为什么这么写:
date
类型支持时间分组。 - 知识点:
date_histogram
聚合按时间间隔分组。
10. 总结
- 字段类型是 Elasticsearch 的“数据分类标签”:
text
:像“故事书”一样支持模糊搜索。keyword
:像“分类标签”一样精确匹配。integer
:像“计算器”一样支持数值计算。date
:像“日历”一样管理时间。
- 核心作用:
确保数据正确存储、高效查询、支持复杂操作(如聚合统计)。 - 底层原理:
根据类型决定如何分词、索引、存储和计算数据。
11. 扩展说明
(1) 字段类型的作用
- 存储优化:
text
存储为分词后的词项,keyword
存储完整值。 - 查询加速:
integer
直接比较数值,date
转换为时间戳。 - 数据完整性:
确保插入的数据类型正确(如price
不能是字符串)。
(2) 常见字段类型总结
text
keyword
integer
date
boolean
12. 总结
- 字段类型是 Elasticsearch 的“数据分类器”:
它像图书标签一样,告诉系统如何处理数据,确保查询高效且准确。 - 核心功能:
支持模糊搜索、精确匹配、数值计算、时间统计。 - 底层原理:
根据类型选择分词、存储、索引的方式,优化查询性能。