ElasticSearch-基础-05-Mapping_数据类型
2025-01-22 08:19:30    2.5k 字   
This post is also available in English and alternative languages.

ElasticSearch版本:6.5.0(点击跳转官方文档)

ElasticSearch Mapping 映射 是定义文档及其包含字段存储和索引方式的过程。


1. ElasticSearch Mapping 数据类型

每个索引都有一种映射类型,用于确定文档的索引方式。

如果把索引看做数据库、类型看做表、映射就是表结构。请注意,这种对比并不好,数据库表可以创建多个,但Elasticsearch6.x版本后,一个index只支持一个type。

使用映射可以用来定义:

  • 哪些字段视为全文字段
  • 哪些字段是包含数字、日期、地理信息的。
  • 日期值的格式
  • 动态添加字段的映射的自定义规则。
  • 等…

2. 查看索引映射

查看已有索引的映射,使用如下命令:

1
2
3
get /books/_mapping/book

get /index_name/_mapping/type

3. 索引映射配置

映射可以分为 动态映射静态映射


3.1. 动态映射

在关系型数据库中,需要先创建数据库,然后在该数据库实例下创建数据表,然后才能在该表中插入数据。

**在Elasticsearch中不需要事先定义映射(Mapping),文档写入Elasticsearch时,会根据文档字段自动识别类型,这种机制称之为动态映射
**


3.1.1. 动态映射规则

动态映射可以帮助我们在创建索引后直接将文档数据写入ElasticSearch,让我们尽快享受到ElasticSearch检索功能。

在实际项目中,如果在导入数据前不能确定包含哪些字段或者不方便确定字段类型,也可以使用动态映射(但不推荐)。

当向es写入一个新文档,其中包含一个之前没有的字段,那么es会通过动态映射来推断该字段类型。

JSON数据自动推测类型
null没有字段被添加
true、falseboolean型
小数float型
数字long型
日期date或text
字符串text
数组由数组第一个非空值决定
JSON对象Object类型

3.2. 静态映射

在Elasticsearch中事先定义好映射(Mapping),包含文档的个个字段及其类型等,这种方法称之为静态映射

动态映射的类型自动推测功能有时并不完全正确,这就需要静态映射机制。

静态映射与关系型数据库中创建表语句,需要事先指定字段类型一样。

相对于动态映射,静态映射可以添加更加详细字段类型、更精准的配置信息等。


3.2.1. 新建静态索引映射

索引名称:books

类型名称:it

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
PUT /books
{
"mappings": {
"it": {
"properties": {
"bookId": {
"type": "long"
},
"bookName": {
"type": "text"
},
"publishDate": {
"type": "date"
}
}
}
}
}

通过head查看

静态映射-1


3.2.2. 插入数据

请求

1
2
3
4
5
6
PUT books/it/1
{
"bookId": "1",
"bookName": "Thinking In Java",
"publishDate": "2019-07-30"
}

3.2.3. 检索

请求

1
GET books/it/1

响应报文

1
2
3
4
5
6
7
8
9
10
11
12
{
"_index": "books",
"_type": "it",
"_id": "1",
"_version": 1,
"found": true,
"_source": {
"bookId": "1",
"bookName": "Thinking In Java",
"publishDate": "2019-07-30"
}
}

4. 静态mapping + 动态mapping

测试一下,如果一个索引已经设置了静态mapping,在新增文档中,多加一个字段,看下是否会报错

新建test_books索引,设置三个主分片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
PUT /test_books
{
"settings": {
"number_of_shards": 3
},
"mappings": {
"it": {
"properties": {
"bookId": {
"type": "long"
},
"bookName": {
"type": "text"
},
"publishDate": {
"type": "date"
}
}
}
}
}

创建完成,然后插入一条正常的文档

1
2
3
4
5
6
POST /test_books/it/
{
"bookId": "1",
"bookName": "Thinking In Java",
"publishDate": "2019-07-30"
}

这个是没有问题

继续插入下面这个文档,新增一个mapping中没有的字段。

1
2
3
4
5
6
7
POST /test_books/it/
{
"bookId": "2",
"bookName": "高性能MySQL",
"publishDate": "2019-11-02",
"bookPrice": 78.5
}

结果也被插入进去了,并没有报错、冲突,看来 静态映射 和 动态映射 并不是对立的。

因此,在插入文档时,需要注意。

静态映射+动态映射


5. 映射类型

在elasticsearch 6.0.0 版本之前,一个索引可以包含多个映射类型

Indices created in Elasticsearch 6.0.0 or later may only contain a single mapping type.
Indices created in 5.x with multiple mapping types will continue to function as before in Elasticsearch 6.x.
Types will be deprecated in APIs in Elasticsearch 7.0.0, and completely removed in 8.0.0.
Removal of mapping types

在elasticsearch 6.0.0 版本之后,索引只能包含一个映射类型。

映射类型包含:

  • 元字段
    元字段用于自定义文档的元数据关联的处理方式。元字段的示例包括文档的_index,_type,_id和_source字段。

  • 字段属性
    与文档相关的字段或属性列表

5.1. Mapping 元字段

每篇文档都有与之关联的元数据,例如_index,mapping _type和_id元字段;创建映射类型时,可以自定义某些元字段的行为。

分类元字段描述
文档属性元字段_index文档所属的索引
_id文档的id
_type文档所属类型
_uid由_type和_id字段组成
文档元字段_source文档的原生json字符串
_size整个_source字段的字节数大小
索引元字段_all自动组合所有的字段值
_field_names文档中包含非空值的所有字段
_ignored文档中由于索引而在索引时被忽略的所有字段
路由元字段_routing自定义路由值,用于将文档路由到特定分片
其他元字段_meta用于自定义元数据

5.2. 字段 属性

注意: String类型在ElasticSearch旧版本中使用较多,从ElasticSearch5.X开始不再支持String,由text和keyword类型代替。


5.2.1. 核心类型

分类字段类型描述
String(字符串型)texttext 是一种允许索引全文的字段类型(text类型字段,存储数据时,会自动分词,并生成索引)
不适合用作排序或聚合(SignificantTerms聚合例外)
keyword只能通过精确值搜索到,不会分词、整段完整精确匹配
Numeric datatypes(数字类型)long带符号的64位整数
integer带符号的32位整数
short带符号的16位整数(-32768~32767)
byte带符号的8位整数(-128~127)
double双精度浮点64位
float单精度浮点32位
half_float半精度浮点16位
scaled_float由长度固定的缩放因子支持的浮点数
Date datatype(日期类型)datees 中的日期可以是:包含格式化日期的字符串,例如"2015-01-01"或"2015/01/01 12:10:30"、一个代表毫秒以来的长数字、表示自纪元以来秒数的整数
Boolean datatype(布尔类型)booleanboolean 字段接受JSON true和false值,但也可以接受被解释为true或false的字符串(false,true、"false","true")
Binary datatype(二进制类型)binarybinary类型接受二进制值作为 Base64编码的字符串。默认情况下不存储该字段,并且不可搜索;
注意:Base64编码的二进制值不得包含嵌入的换行符\n

5.2.2. 复杂数据类型

分类字段类型描述
Range datatypes(范围类型)
支持以下范围类型:
integer_range32位整数,最小值:-2^31,最大值:2^31-1
float_range单精度32位
long_range64位整数,最小值:-2^63,最大值:2^63-1
double_range双精度64位
date_range一系列日期值,表示为自系统纪元以来经过的无符号64位整数毫秒
ip_range支持IPv4或IPv6(或混合)地址的一系列ip值
Complex datatypes(复杂数据类型)Object datatype文档可能包含内部对象,而内部对象本身可能又包含内部对象
Nested datatypenested类型是object数据类型的专用版本,它允许对象数组以可以彼此独立查询的方式进行索引

5.2.3. Geo 数据类型

暂时用不到,后面再研究


5.2.4. 专用数据类型

暂时用不到,后面再研究


6. Mapping参考模版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
PUT testinfo_index
{
"mappings": {
"testinfo_type": {
"properties": {
"id": {
"type": "long"
},
"title": {
"type": "keyword"
},
"content": {
"analyzer": "ik_max_word",
"type": "text",
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
},
"available": {
"type": "boolean"
},
"review": {
"type": "nested",
"properties": {
"nickname": {
"type": "text"
},
"text": {
"type": "text"
},
"stars": {
"type": "integer"
}
}
},
"publish_time": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"expected_attendees": {
"type": "integer_range"
},
"ip_addr": {
"type": "ip"
},
"suggest": {
"type": "completion"
}
}
}
}
}
}
}

注:模版来自 干货 | Elasticsearch5.X Mapping万能模板

或者,也可以使用curl命令进行创建:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
curl -H "Content-Type: application/json" -XPUT 'http://127.0.0.1:9200/testdata' -d '{
"settings": {
"number_of_shards": 1
},
"mappings": {
"dataType": {
"properties": {
"name": {
"type": "keyword"
},
"address": {
"type": "keyword"
},
"activityStartTime": {
"type": "keyword"
},
"val": {
"type": "text"
}
}
}
}
}'

7. 参考文档