摘要
如何打造出色的 Elasticsearch mapping?动态 mapping 可以灵活应对不同数据类型,但也可能会影响性能。显式 mapping 可以关闭动态 mapping,确保数据类型的准确性。
正文
怎样设计方案一个性能卓越 Elasticsearch mapping
文件目录
- 序言
- mapping
- mapping 能干什么
- Dynamic mapping
- dynamic=true
- dynamic=runtime
- dynamic=false
- dynamic=strict
- 是不是能够 改动 mapping 中的基本数据类型
- 关掉 dynamic mapping
- Explicit mapping
- text 种类
- keyword 种类
- date 种类
- numeric 种类
- boolean 种类
- 其他类型
- 汇总
序言
在关联型概念模型设计之中,表的设计方案特别是在关键,殊不知关联型数据库查询更关心的表与表中间的关联,及其表的区划是不是有效,而 Elasticsearch
中却更为关心字段名种类的设计方案,一个好的字段种类设计方案能够 更强的运用 Elasticsearch
的检索剖析特点。
mapping
假如说大家要想用好 Elasticsearch
,那麼就务必要先掌握 mapping
什么叫 mapping
。一句话:mapping
是界定怎样储存和数据库索引文本文档以及包括的字段名的全过程。
mapping 能干什么
前边大家提及,在 Elasticsearch
中,mapping
类似传统式关联型数据库查询的表构造界定,关键做下列一些事:
- 界定字段名称和字段名种类。
- 界定全文索引有关的配备,例如是不是被数据库索引,是不是能够 被词性标注等。
mapping
能够 分成二种:Dynamic mapping
和 Explicit mapping
。
Dynamic mapping
Dynamic mapping
即:动态性投射。动态性投射说白了便是 mapping
会被实例化,换句话说大家不用界定 mapping
就可以往一个数据库索引插进数据信息,插进数据库索引数据信息以后,Elasticsearch
会依据插进的数据信息全自动推断基本数据类型,从而动建立 mapping
。
例如下边便是往一个不会有的数据库索引 index_001
插进一条数据信息:
PUT index_001/_doc/1
{
"name":"lonely wolf",
"age": 18,
"create_date":"2021-05-19 20:45:11",
"update_date":"2021-05-23"
}
插进数据信息以后,实行 GET index_001
来查看一下数据库索引信息内容:
能够 发觉,此刻数据库索引早已被全自动建立了,并且 age
字段名被 Elasticsearch
界定为 long
种类,update_date
被界定为 data
种类,别的2个字段名则被推断为 text
种类。
Elasticsearch
中全自动投射种类标准能够 根据 dynamic
主要参数开展配备,dynamic
种类有 4
种:
dynamic=true
初始值。当设定为 true
时,一旦有新字段插进文本文档,则 mapping
会被同歩升级。
大家在上面的文本文档中再插进一个新文本文档,新文本文档增加一个 address
字段名:
PUT index_001/_doc/2
{
"name":"lonely wolf2",
"age": 20,
"create_date":"2021-05-23 11:37:11",
"update_date":"2021-05-23",
"address":"广东省深圳市"
}
随后再查询一下 mapping
,能够 见到 mapping
早已增加了一个 address
字段名,mapping
字段名被升级代表着该字段名会添加数据库索引:
dynamic=runtime
这一种类和 true
种类十分类似,可是有一个十分大的差别便是,尽管添加新字段也会升级 mapping
,可是新添加的字段名不容易被数据库索引,也就是不容易促使数据库索引增大,但是尽管不被数据库索引,可是新添加的字段依然能够 被查看,仅仅查看的成本会更高。因此 这类种类一般不建议用在常常查看的标准字段名上,而更合适用在一些不确定性算法设计的日志类数据库索引中。
改动 dynamic
种类:
PUT index_001/_mapping
{
"dynamic": "runtime"
}
增加一个文本文档,并添加一个新字段:
PUT index_001/_doc/3
{
"email":"123@qq.com"
}
最终询一下 mapping
,能够 见到字段名特性是 runtime
,并且种类是 keyword
:
下表便是全自动建立 mapping
时,Elasticsearch
的投射关联:
插进基本数据类型 | dynamic=true | dynamic=runtime |
---|---|---|
null | 不容易加上一切字段名 | 不容易加上一切字段名 |
true 或 false | boolean | boolean |
double | float | double |
integer | long | long |
object | object | object |
string(根据 date 校检) | date | date |
string(根据 numreic 校检) | float 或 long | double 或 long |
string(沒有根据 date 或 numreic 校检) | text ,而且另外会建立一个 keyword 子域 | keyword |
array | 在于二维数组中第一个非 null 值 | 在于二维数组中第一个非 null 值 |
PS:keyword
表明 不参加词性标注。
dynamic=false
当设定为 false
时,新添加的字段名不容易被升级到 mapping
,换句话说新字段不容易被数据库索引,故以这一字段名为标准开展检索时,没法被检索到(这一点要留意和 runtime
种类开展区别),但是尽管没法被数据库索引,可是该字段名会发生在 _source
中。换句话说该字段名不可以做为查询条件,可是能被查看出去。
下面大家将 dynamic
改动为 false
,并增加一个字段名来认证,能够 发觉增加的字段名会发生在 _source
中,可是没法做为标准被查看出去:
dynamic=strict
这类种类更为严苛,表明不允许增加一个没有 mapping
中的字段名,一旦增加的字段名没有 mapping
界定中,则立即出错:
是不是能够 改动 mapping 中的基本数据类型
在 Elasticsearch
中,一旦一个字段名被界定在了 mapping
中,是没法被改动的,由于一旦字段名被改动了,便会没法被数据库索引(增加字段名以外),因此 一般大家必须改动数据库索引得话,都是会复建数据库索引,并选用 reindex
实际操作来转移数据信息。
关掉 dynamic mapping
能够 根据下列2个配备来关掉 dynamic mapping
,下列2个特性初始值均为 true
,假如必须关掉,则必须改动为 false
:
action.auto_create_index: true
index.mapper.dynamic: true
Explicit mapping
Explicit mapping
即:显式投射。换句话说此刻大家必须表明的界定字段名种类。
Elasticsearch
中适用的字段名种类许多,在这儿就举一些较为常见的字段名种类:
text 种类
它是最常见的一种种类,储存字符串数组,用以全文索引。当字段名被界定为 text
种类时,默认设置不可以用以汇聚,排列等实际操作:
能够 见到,用 text
种类字段名排列报告凑,假如要想容许这种实际操作,能够 根据设定 fielddata=true
,以下
PUT my-index-011/_mapping
{
"properties": {
"my_field": {
"type": "text",
"fielddata": true
}
}
}
field
字段名储存在堆内存中,由于其牵涉到的测算较为耗费特性,因此 一般不建议设定 fielddata=true
,只是根据创建一个 keyword
子域来完成(默认设置方法):
PUT index_111
{
"mappings": {
"properties": {
"my_field": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
}
这类界定方法我们可以将一个字段名另外做为 text
和 keyword
种类应用,假如要用以汇聚或是排列等实际操作则能够 应用 字段名.keyword
来做为字段名来开展实际操作:
keyword 种类
这类种类也十分常见,该字段名储存的数指一个总体,不能被词性标注,因此 一般不容易用于界定大文中的全文搜索字段名,只是用于储存一些结构型的字符串数组,例如:id,电子邮箱,标识等。
keyword
种类一般用以汇聚,排列等实际操作。此外,该字段名也有二种衍化种类:constant_keyword
和 wildcard
。
constant_keyword
:一般用以界定变量定义种类,例如一个数据库索引中某一个字段名所有为同一个值,能够 界定为这类种类。wildcard
:一般用以模糊匹配查看或是正则匹配查看。
以下便是一个模糊匹配查看的实例(能够 相互配合使用通配符应用,类似关联型数据库查询的 like
实际操作):
GET index_112/_search
{
"query": {
"wildcard": {
"my_wildcard": {
"value": "*quite*lengthy"
}
}
}
}
date 种类
用以界定日期种类,界定日期种类的另外,能够 根据 format
来特定日期的文件格式:
PUT index_113
{
"mappings": {
"properties": {
"date": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" }
}
}
}
numeric 种类
Elasticsearch
中给予了比较多的文件格式用于表明不一样长短的数据种类:
数据种类 | 长短 |
---|---|
long | 64 位有标记整数金额。范畴:-2 的 63 三次方到 2 的 63 三次方 -1 |
integer | 32 位有标记整数金额。范畴:-2 的 31 三次方到 2 的 31 三次方 -1 |
short | 16 位有标记整数金额。范畴:-32768 到 32767 |
byte | 8 位有标记整数金额。范畴:-128 到 127 |
double | 64 位双精度小数 |
float | 32 位单精度小数 |
half_float | 16 位单精度小数 |
scaled_float | 含有放缩因素的浮点型,一般适用储放额度这类的数据信息。例如 18.88 元,放缩因素是 100,那麼在数据库索引的时候会被数据库索引为 1888(即:原值 * 放缩因素) |
unsigned_long | 64 位无符号整数。范畴:0 到 2 的 64 三次方减 1 |
界定方法以下所显示:
PUT index_002
{
"mappings": {
"properties": {
"number_of_bytes": {
"type": "integer"
},
"time_in_seconds": {
"type": "float"
},
"price": {
"type": "scaled_float",
"scaling_factor": 100
}
}
}
}
boolean 种类
布尔类型非常简单,仅有 true
和 false
二种:
PUT index_001
{
"mappings": {
"properties": {
"is_published": {
"type": "boolean"
}
}
}
}
其他类型
除开上边详细介绍的一些较为常见的基本数据类型,Elasticsearch
中也有一些高級基本数据类型:如 Nested(嵌入种类),自然地理基本数据类型,ip
种类等。
汇总
Elasticsearch
中适用动态性 mapping
和表明 mapping
二种,在应用中有时能够 先插进一条数据信息到临时性数据库索引,等自动生成 mapping
以后,在对目前 mapping
开展改动调节,在字段名上特别是在要考虑到好 text
种类和 keyword
种类的设定,假如必须适用全文检索和词性标注检索,则必须应用 text
种类,必须适用关键词模糊查询或是汇聚排列等实际操作能够 考虑到应用 keyword
字段名。
关注不迷路
扫码下方二维码,关注宇凡盒子公众号,免费获取最新技术内幕!
评论0