ElasticSearch的映射与文档

概述

映射官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/7.17/mapping.html

映射(mapping)是ES中一个很重要的概念,我们知道ES的索引类似于MySQL中的表,而映射就类似于MySQL中的表结构,而文档(Document)就是MySQL表中的一行行数据。

映射(Mapping)的作用是定义文档的结构与数据类型,同时也能设置如何对文档进行索引

映射分为动态映射和显示映射

  • 动态映射是只需在ES中添加文档即可自动添加新字段。您可以将字段添加到顶级映射以及内部object 和nested外部字段。
  • 显示映射是需要你添加文档前定义好每个字段的数据类型,例如:
    • 哪些字符串字段应被视为全文字段
    • 哪些字段包含数字、日期或地理位置
    • 日期值的 格式
    • 自定义规则来控制动态添加字段 的映射

数据类型介绍

官方文档:https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/field-data-types

常见类型

  • binary

    • 存储编码为 Base64 字符串的二进制值类型。
  • boolean

    • 只包含true和false两个值
  • keyword

    • 用于结构化内容,例如 ID、电子邮件地址、主机名、状态代码、邮政编码或标签。使用分词器时不会被分词
  • text

    • 用于全文内容(例如电子邮件正文或产品描述)的传统字段类型。适合全文检索
  • date

    • 用于存储日期,可使用format指定格式化类型
  • 数字

    • ES中数字类型有很多种,基本的可参考Java中的数据类型
      • byte:一个有符号的 8 位整数,最小值为-128,最大值为127
      • short:一个有符号的 16 位整数,最小值为-32,768,最大值为32,767
      • integer:一个有符号的 32 位整数,最小值为-231,最大值为231 - 1
      • long:一个有符号的 64 位整数,最小值为-263,最大值为263 - 1。
      • double:双精度 64 位 IEEE 754 浮点数,限制为有限值。
      • float:单精度 32 位 IEEE 754 浮点数,限制为有限值。
      • half_float:半精度 16 位 IEEE 754 浮点数,限制为有限值。
      • scaled_float:由 支持的浮点数long,按固定double比例因子缩放
      • unsigned_long:一个无符号的 64 位整数,最小值为 0,最大值为2^64 - 1
  • 数组

    • Elasticsearch 没有专门的array数据类型。默认情况下,任何字段都可以包含零个或多个值,但是,数组中的所有值必须属于相同的数据类型。例如:
      • 字符串数组:[ "one", "two"]
      • 整数数组:[ 1, 2]
      • 数组的数组: [ 1, [ 2, 3]] 相当于 [ 1, 2, 3]
      • 对象数组:[ { "name": "Mary", "age": 12 }, { "name": "John", "age": 10 }]
  • 对象

    • JSON 文档本质上是分层的:文档可能包含内部对象,而内部对象本身又可能包含内部对象:
  • IP

    • 用于存储IPv4或IPv6地址。

常用的数据类型就是以上几种,如果需要其它的场景,可以参考官方文档

映射的管理

创建映射

静态映射(显示创建)

创建索引时定义映射,控制字段类型和配置:

PUT /my_index {   "settings": {     "number_of_shards": 3,     "number_of_replicas": 1,     "refresh_interval": "1s"   }   // 定义映射   "mappings": {     "properties": {       "title": { "type": "text" },       "price": { "type": "double" },       "tags": { "type": "keyword" },       "created_at": { "type": "date", "format": "yyyy-MM-dd" }     }   } } 

动态映射(自动创建)

当插入文档时,如果字段不存在,ES 会根据数据类型自动创建映射。例如:

PUT /my_index/_doc/1 {   "title": "Elasticsearch Guide",   "price": 49.99,   "tags": ["search", "database"] } 

ES 会自动为字段 title(text+keyword)、price(double)和 tags(keyword)创建映射。

查看映射

  • 查看单个索引的映射
GET /my_index/_mapping 
  • 查看多个索引的映射
GET /index1,index2/_mapping 
  • 查看所有索引的映射
GET /_mapping 

更新映射

新增字段(支持动态更新)
可以向现有映射添加新字段:

PUT /my_index/_mapping {   "properties": {     "description": { "type": "text" },     "in_stock": { "type": "boolean" }   } } 

修改字段类型(不支持直接修改)
若需修改现有字段类型,需创建新索引并重新索引数据:

// 1. 创建新索引并定义正确的映射 PUT /new_my_index {   "mappings": {     "properties": {       "price": { "type": "integer" } // 原类型为double,现改为integer     }   } }  // 2. 使用_reindex API迁移数据 POST /_reindex {   "source": { "index": "my_index" },   "dest": { "index": "new_my_index" } }  // 3. 验证数据后删除旧索引 DELETE /my_index 

删除映射

  • 删除索引(同时删除映射)
DELETE /my_index 
  • 重置映射(删除后重建)
    删除索引后重新创建并定义新映射:
DELETE /my_index PUT /my_index {   "mappings": { ... } // 新映射定义 } 

映射参数详解

核心参数

  • type:字段类型(text、keyword、integer 等)
  • index:是否索引(true/false)
  • analyzer:指定分词器(如 standard、english)
  • search_analyzer:搜索时使用的分词器(与 analyzer 不同时生效)
  • null_value:替代 null 值的默认值(需与字段类型匹配)
  • dynamic:控制动态添加字段的行为(true/false/strict)

高级参数

  • copy_to:将字段值复制到目标字段,便于组合搜索
  • doc_values:是否存储列式数据(用于聚合和排序,默认 true)
  • norms:是否存储归一化因子(影响评分,text 默认 false)
  • fields:多字段索引(如同时存储 text 和 keyword 类型)

文档的管理

在 Elasticsearch(ES)中,文档(Document)是可被索引的基本数据单元,以 JSON 格式存储

下面只列举了常用的文档管理的api,如果想要了解其它的可以参考官方文档:https://www.elastic.co/docs/api/doc/elasticsearch/group/endpoint-document

文档的基本概念

  • 文档结构:JSON 对象,包含字段和值。
  • 唯一性标识:每个文档在索引中需有唯一 ID(可自动生成或手动指定)。
  • 元数据字段:
    • _index:文档所在的索引名。
    • _id:文档的唯一标识符。
    • _source:原始 JSON 文档。
    • _version:文档版本号,用于乐观锁。

创建文档

指定id创建

PUT /my_index/_doc/1 {   "title": "Getting Started with ES",   "content": "First steps in Elasticsearch",   "user": "john_doe",   "views": 100 } 

自动生成id

返回结果包含自动生成的_id。

POST /my_index/_doc {   "title": "Elasticsearch Tutorial",   "content": "Learn Elasticsearch basics",   "tags": ["search", "database"],   "created_at": "2023-01-01" } 

获取文档

根据 ID 获取单个文档

GET /my_index/_doc/1 

检查文档是否存在

HEAD /my_index/_doc/1 

获取文档中指定的字段

GET /my_index/_doc/1?_source=filed1,filed2 

更新文档

全量更新

PUT /my_index/_doc/1 {   "title": "Updated Title",  // 原文档的其他字段会被删除   "views": 101 } 

部分更新

POST /my_index/_update/1 {   "doc": {     "views": 102,           // 仅更新views字段     "updated_at": "now"     // 添加新字段   } } 

删除文档

根据 ID 删除单个文档

DELETE /my_index/_doc/1 

基于查询条件删除(需启用 delete-by-query 插件)

POST /my_index/_delete_by_query {   "query": {     "term": {       "user": "john_doe"     }   } } 

动态映射详解

官方文档:https://www.elastic.co/docs/manage-data/data-store/mapping/dynamic-mapping
动态映射是只需在ES中添加文档即可自动添加新字段。您可以将字段添加到顶级映射以及内部object 和nested外部字段。

验证动态映射

创建一个索引,无需指定映射

PUT dynamic-mapping-01 {   "settings": {     "number_of_shards": 3,     "number_of_replicas": 1,     "refresh_interval": "1s"   } } 

添加一个文档

# 请求 PUT dynamic-mapping-01/_doc/1 {   "create_date": "2015/09/02",   "name": "huangsir",   "age": 18,   "addr": "BeiJing",   "ip": "10.0.0.40" } 

查询文档

# 请求 GET dynamic-mapping-01/_doc/1  # 预期返回 {   "_index" : "dynamic-mapping-01", //索引名称   "_type" : "_doc", // 类型   "_id" : "1",    // 唯一标识   "_version" : 1, //版本号   // 排序   "_seq_no" : 0,   // 分片   "_primary_term" : 1,   "found" : true,   // 添加的数据   "_source" : {     "create_date" : "2015/09/02",     "name" : "huangsir",     "age" : 18,     "addr" : "BeiJing",     "ip" : "10.0.0.40"   } } 

查看映射

# 请求 GET /dynamic-mapping-01/_mapping  # 预期返回 {   "dynamic-mapping-01" : {     "mappings" : {       "properties" : {         "addr" : {           "type" : "text",           "fields" : {             "keyword" : {               "type" : "keyword",               "ignore_above" : 256             }           }         },         "age" : {           "type" : "long"         },         "create_date" : {           "type" : "date",           "format" : "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis"         },         "ip" : {           "type" : "text",           "fields" : {             "keyword" : {               "type" : "keyword",               "ignore_above" : 256             }           }         },         "name" : {           "type" : "text",           "fields" : {             "keyword" : {               "type" : "keyword",               "ignore_above" : 256             }           }         }       }     }   } } 

通过上面的验证,发现其对应的字段的数据类型并不是我们想要的,我们可以指定其数据类型

验证静态映射

官方文档:https://www.elastic.co/docs/manage-data/data-store/mapping/explicit-mapping

静态映射是在创建索引时指定映射的字段、数据类型及其它相关的配置

创建索引

# 请求 PUT explicit-mapping-01 {   "settings": {     "number_of_shards": 3,     "number_of_replicas": 1,     "refresh_interval": "1s"   },   "mappings": {     "properties": {       "name": {         "type": "text"       },       "age": {         "type": "byte"       },       "addr": {         "type": "keyword"       },       "ip": {         "type": "ip"       },       "create_date": {         "type": "date",         "format": "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis"       },       "class": {         "type": "object",          "properties": {           "name":{             "type": "text"           }         }       }     }   } }  # 预期返回 {   "acknowledged" : true,   "shards_acknowledged" : true,   "index" : "explicit-mapping-01" } 

查看映射

# 请求 GET explicit-mapping-01/_mapping  # 预期返回 {   "explicit-mapping-01" : {     "mappings" : {       "properties" : {         "addr" : {           "type" : "keyword"         },         "age" : {           "type" : "byte"         },         "class" : {           "properties" : {             "name" : {               "type" : "text"             }           }         },         "create_date" : {           "type" : "date",           "format" : "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis"         },         "ip" : {           "type" : "geo_point"         },         "name" : {           "type" : "text"         }       }     }   } } 

创建文档

# 请求 POST explicit-mapping-01/_doc {   "create_date": "2015/09/02",   "name": "huangsir",   "age": 18,   "addr": "BeiJing",   "ip": "10.0.0.40",   "class": {     "name": "清华大学"   } }  # 预期返回 {   "_index" : "explicit-mapping-01",   "_type" : "_doc",   "_id" : "C0JSlpcB-K0y8avWYdSX",   "_version" : 1,   "result" : "created",   "_shards" : {     "total" : 2,     "successful" : 2,     "failed" : 0   },   "_seq_no" : 0,   "_primary_term" : 1 }  

查看文档

# 请求 GET explicit-mapping-01/_doc/C0JSlpcB-K0y8avWYdSX  # 预期返回 {   "_index" : "explicit-mapping-01",   "_type" : "_doc",   "_id" : "C0JSlpcB-K0y8avWYdSX",   "_version" : 1,   "_seq_no" : 0,   "_primary_term" : 1,   "found" : true,   "_source" : {     "create_date" : "2015/09/02",     "name" : "huangsir",     "age" : 18,     "addr" : "BeiJing",     "ip" : "10.0.0.40",     "class" : {       "name" : "清华大学"     }   } } 

发表评论

评论已关闭。

相关文章