不,Elasticsearch 索引(Index) ≠ Mapping。
这是两个紧密关联但本质不同的概念:

  • 索引(Index)数据的容器(类似数据库中的“表”)
  • Mapping(映射)索引的结构定义(类似“表结构”或“Schema”)

将二者等同,会导致对 ES 数据模型的根本性误解。


一、本质区别:容器 vs 结构

维度 索引(Index) Mapping(映射)
角色 数据存储单元 字段结构定义
类比 MySQL 的 数据库表(table) MySQL 的 表结构(CREATE TABLE …)
内容 包含文档(Documents)、分片(Shards)、设置(Settings) 定义字段类型(text/keyword/integer)、分析器、是否可聚合等
变更 可动态增删文档 字段类型一旦设定,不可修改(需重建索引)

💡 核心认知
Mapping 是 Index 的“基因蓝图”,Index 是 Mapping 的“物理载体”


二、包含关系:Index 包含 Mapping

一个完整的 Index 定义包含两部分:

PUT /products
{
  "settings": { ... },   // ← 索引设置(分片数、刷新间隔等)
  "mappings": { ... }    // ← 映射(字段结构定义)
}
▶ 1. Settings(设置)
  • 控制 索引的物理行为
    {
      "number_of_shards": 3,
      "number_of_replicas": 1,
      "refresh_interval": "30s"
    }
    
▶ 2. Mappings(映射)
  • 控制 数据的逻辑结构
    {
      "properties": {
        "name": { "type": "text" },
        "price": { "type": "float" },
        "brand": { "type": "keyword" }
      }
    }
    

关键结论
Mapping 是 Index 的子集,Index 是 Mapping 的宿主


三、实战中的典型误区

▶ 误区 1:“创建了 Index 就有 Mapping”
  • 事实
    • 若未显式定义 Mapping,ES 会根据 第一条文档 动态生成
    • 动态 Mapping 常导致 字段类型错误(如字符串数字被设为 text
  • 后果
    • 无法范围查询(range
    • 聚合结果异常
  • 正确做法
    始终显式定义 Mapping
    PUT /products
    {
      "mappings": {
        "properties": {
          "user_id": { "type": "long" },  // 避免被设为 text
          "name": { "type": "text" }
        }
      }
    }
    
▶ 误区 2:“修改 Mapping 就是修改 Index”
  • 事实
    • 字段类型不可变(如 textkeyword 需重建索引)
    • 只能 新增字段,不能修改现有字段类型
  • 正确流程
    1. 创建新索引(带正确 Mapping)
    2. _reindex 迁移数据
    3. 切换别名(Alias)
▶ 误区 3:“Index 名称影响 Mapping”
  • 事实
    • Index 名称仅用于路由和管理
    • 同一 Mapping 可用于多个 Index(如日志按天分索引:logs-2024-07-24

四、PHP 实战:Laravel 中的 Index 与 Mapping

▶ 步骤 1:创建 Index + Mapping
$client = \Elasticsearch\ClientBuilder::create()->build();

$params = [
    'index' => 'products',
    'body' => [
        'settings' => [
            'number_of_shards' => 1,
            'refresh_interval' => '30s'
        ],
        'mappings' => [
            'properties' => [
                'name' => [
                    'type' => 'text',
                    'fields' => ['keyword' => ['type' => 'keyword']]
                ],
                'price' => ['type' => 'float'],
                'user_id' => ['type' => 'long'] // 关键!避免 text
            ]
        ]
    ]
];

$client->indices()->create($params);
▶ 步骤 2:验证 Mapping
// 获取当前 Mapping
$mapping = $client->indices()->getMapping(['index' => 'products']);
print_r($mapping['products']['mappings']);

五、终极心法

**“Index 不是结构,
而是数据的家园——

  • 当你 定义 Mapping
    你在设计家园蓝图;
  • 当你 创建 Index
    你在建造物理空间;
  • 当你 协同二者
    你在构建高效搜索系统。

真正的 ES 大师,
始于对概念的敬畏,
成于对细节的精控。”


结语

从今天起:

  1. 所有 Index 必显式定义 Mapping
  2. ID/数字字段必用 long/integer
  3. 修改字段类型必走 Reindex 流程

因为最好的搜索系统,
不是临时拼凑,
而是结构先行。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。