Elasticsearch到底为什么需要Mapping?一共包含哪些部分?使用场景是什么?底层原理是什么?

1. 为什么需要 Mapping?

(1) 核心原因
  • 告诉 Elasticsearch 怎么处理数据
    比如,“这个字段是数字?还是文字?需要分词吗?”

    • 如果字段是“价格”,应该用数字类型(方便排序和计算)。
    • 如果字段是“标题”,需要分词才能支持全文搜索(比如“小王子”会被拆分成“小”、“王”、“子”)。
  • 避免自动推断的错误
    如果不指定 Mapping,Elasticsearch 会自动猜测字段类型,但可能不准确。

    • 比如,“123”可能是数字,也可能是字符串(比如订单号“ORD123”)。

(2) Mapping 包含哪些部分?
  1. 字段类型(Field Types)

    • text:用于全文搜索(如文章内容)。
    • keyword:用于精确匹配(如分类名称)。
    • integer:整数类型(如年份)。
    • date:日期类型(如“2023-10-01”)。
  2. 字段参数(Field Parameters)

    • store:是否存储原始值(默认不存储,节省空间)。
    • index:是否建立索引(不建立索引的字段无法搜索)。
    • analyzer:分词器(如中文分词用 ik_max_word)。
  3. 映射参数(Mapping Parameters)

    • dynamic:是否自动添加新字段(默认允许)。
    • dynamic_templates:为未知字段设置默认类型。

(3) 使用场景
  • 电商商品搜索

    • title 字段用 text 类型(支持“小王子”搜索)。
    • price 字段用 integer 类型(支持价格过滤)。
    • category 字段用 keyword 类型(精确匹配“小说”分类)。
  • 日志分析

    • timestampdate 类型(按时间排序)。
    • error_messagetext 类型(支持模糊搜索错误原因)。

(4) 底层原理

Mapping 是 Elasticsearch 的“数据处理说明书”:

  1. 分词(Tokenization)

    • text 字段会被拆分成单词(如“小王子” → [小, 王, 子])。
    • keyword 字段不会拆分(保持完整,如“小说” → ["小说"])。
  2. 倒排索引构建

    • 根据字段类型,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'],
  1. 作用:将 title 字段定义为 text 类型,支持全文搜索。
  2. 为什么这么写text 类型会自动分词(如“小王子” → “小”、“王”、“子”),方便模糊匹配。
  3. 知识点:Elasticsearch 的 字段类型
'author' => ['type' => 'keyword'],
  1. 作用:将 author 字段定义为 keyword 类型,用于精确匹配。
  2. 为什么这么写:作者名称需要精确查找(如“圣埃克苏佩里”必须完全匹配)。
  3. 知识点keyword 类型的不可分词特性。
'price' => ['type' => 'float', 'store' => true],
  1. 作用:定义 price 为浮点数,并存储原始值。
  2. 为什么这么写storetrue 时,查询结果会直接返回原始价格值。
  3. 知识点:字段的 store 参数。
第 6 步:查询测试
'match' => ['title' => '王子']
  1. 作用:搜索 title 中包含“王子”(分词后的“王”或“子”均可匹配)。
  2. 为什么这么写text 字段已分词,支持模糊搜索。
  3. 知识点match 查询的全文搜索特性。
'term' => ['tags' => '童话']
  1. 作用:精确匹配 tags 中的“童话”标签。
  2. 为什么这么写tagskeyword 类型,term 查询精确匹配。
  3. 知识点term 查询与 keyword 类型的配合。

7. 总结

  • Mapping 是数据的“说明书”:告诉 Elasticsearch 如何存储和搜索每个字段。
  • 核心功能:定义字段类型、控制分词、优化查询性能。
  • 底层原理:通过 Mapping 指导分词和倒排索引的构建,实现高效搜索。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值