Skip to content

映射基础

什么是映射?

映射(Mapping) 用来定义索引中字段的类型与行为,例如:是否分词、是否存储、用什么分析器等。可以类比为关系型数据库的表结构(Schema)。映射一旦确定,已存在字段的类型不能修改,只能通过 Reindex 迁移到新索引。


动态映射(Dynamic Mapping)

若不显式指定 mapping,在首次写入文档时,Elasticsearch 会根据 JSON 值的类型自动推断字段类型并创建映射,这就是动态映射

常见对应关系:

JSON 类型推断的 ES 类型
字符串 "hello"text(并带 keyword 子字段,因版本而异)
整数 42long
小数 3.14floatdouble
布尔 true/falseboolean
日期字符串(如 ISO8601)可能被识别为 date
对象 {}object
数组由数组元素类型决定

动态映射的优点是上手快、灵活;缺点是可能推断出不符合预期的类型(例如希望某字段做精确匹配却被当成 text),生产环境建议对关键索引使用显式映射


显式映射(Explicit Mapping)

创建索引时通过 mappings 指定各字段类型:

http
PUT /books
{
  "settings": { "number_of_shards": 1, "number_of_replicas": 0 },
  "mappings": {
    "properties": {
      "title":   { "type": "text" },
      "author":  { "type": "keyword" },
      "year":    { "type": "integer" },
      "price":   { "type": "float" },
      "on_sale": { "type": "boolean" },
      "publish_date": { "type": "date" }
    }
  }
}

常用类型一览:

类型说明
text全文检索,会分词,不用于排序/聚合(通常用子字段 keyword)
keyword不分词,精确匹配、排序、聚合
long / integer / short整数
float / double浮点数
date日期,可指定 format
boolean布尔
object嵌套对象,子字段在 properties 下
nested嵌套数组(每个元素独立存储,便于嵌套查询)
ipIPv4/IPv6
geo_point经纬度

text 与 keyword 的区别(新手必考)

  • text:会对内容分词,用于全文检索(match 等)。默认不用于排序、聚合(因为按词存)。
  • keyword不分词,把整段字符串当作一个整体,用于精确匹配(term/terms)、排序聚合

例如:"title": "Elasticsearch 教程"

  • titletext:可能被分成 elasticsearch教程 等词,用 match 搜“教程”能命中。
  • titlekeyword:只有完整匹配 "Elasticsearch 教程" 才能命中。

多字段:同时支持全文与精确

同一字段常需要“可搜索”又“可聚合/排序”,可用 fields 同时保留 text 与 keyword:

http
PUT /products
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "fields": {
          "keyword": { "type": "keyword" }
        }
      }
    }
  }
}
  • 搜索用:name(text)。
  • 排序/聚合/精确匹配用:name.keyword(keyword)。

映射的查看与修改

  • 查看GET /索引名/_mapping
  • 修改:已存在字段的 type 不能改;只能新增字段,或通过 Reindex 把数据迁到带新 mapping 的索引(见 常用运维操作)。

索引模板(Index Template)

索引模板可以在创建新索引时自动套用相同的 settingsmappings,适合按时间滚动的索引(如按天建的日志索引)。

示例:匹配 logs-* 的索引都使用同一模板:

http
PUT _index_template/logs_template
{
  "index_patterns": ["logs-*"],
  "template": {
    "settings": { "number_of_shards": 1, "number_of_replicas": 0 },
    "mappings": {
      "properties": {
        "message": { "type": "text" },
        "level":   { "type": "keyword" },
        "@timestamp": { "type": "date" }
      }
    }
  }
}

之后创建 logs-2024-01-01 等索引时,会自动应用上述配置。多个模板命中同一索引时,按优先级合并(priority 高的覆盖低的)。