ELK--- Elastic Stack映射和数据类型

Mapping映射介绍

概念:自动或手动为index中的文档建立的一种数据结构和相关配置,称为mapping映射。

如果很难理解,可以把ES中的文档想象成MySQL数据库中的Table表,而映射就是对表中的字段创建对应的数据类型。

一般来说,Mapping映射分为自动映射和手动映射。

自动映射

在第一次在插入数据时,ES自动创建索引,同时也会对插入的数据创建相对应的数据类型和分词器,我们将此称为自动映射。

演示:

  • 插入一条数据
    在这里插入图片描述

  • 使用语法 GET /index/_mapping 查询映射。
    在这里插入图片描述

{
  "student" : {
    "mappings" : {
      "properties" : {
        "age" : {
          "type" : "long"
        },
        "birthday" : {
          "type" : "date"
        },
        "name" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

可以看到的是,我们并未对字段的数据类型进行定义,而在ES中,自动将name 定义为了textage 定义为了longbirthday 定义为了date,这就是ES所提供的自动映射。

手动映射

有时候自动映射的未必是我们想要的,此时可以通过手动设置映射。

创建步骤:

  • 创建索引
    语法: PUT /index
    在这里插入图片描述

  • 手动创建映射
    语法:PUT /index/_mapping

PUT /student/_mapping
{
  "properties": {
           "name": {
              "type": "text"
            },
            "age":{
             "type":"short"
           },
           "birthdy":{
             "type":"date"
           },
           "description": {
              "type": "text",
              "analyzer":"english",
              "search_analyzer":"english"
            }
    }
}

在这里插入图片描述

  • 查询映射类型
    在这里插入图片描述
    此时的age字段类型改成了short

创建映射的格式可以参考上方的格式,在properties中对字段进行设置,其中description字段中的analyzer(分词器)会在之后的文章中介绍。

修改映射

对于想要修改映射,只能创建index时手动建立mapping映射,或者新增字段mapping映射,但是不能修改字段的mapping映射。因为已有数据按照映射早已分词存储好,因此无法修改。

新增一个字段mapping:
语法:PUT /index/_mapping

PUT /student/_mapping
{
  "properties": {
           "hobbys": {
              "type": "text"
            }
    }
}

在这里插入图片描述

此时就为student文档新增了一个hobbys(把y变i加es,大学英语水平变小学了哈哈哈哈)映射。

删除映射

通过删除索引来删除映射。
语法:DELETE /index

删除操作简单粗暴!!!这里就不做演示了。

ES数据类型

ES和其它的NoSQL数据库一样,支持文档中字段的多种不同数据类型。

这里只对常用的做一些介绍,具体可以参考ES数据类型官方文档

在这里插入图片描述

String类型

Text

Text是用于索引全文值的字段,意思就是例如有一个text类型文本存储了以下内容:杰瑞张的不丑的话也挺帅的,当搜索杰瑞挺帅的(扎心了)的时候,就会搜出上面的内容,这就是全文检索。

常用参数:

  • analyzer
    通过analyzer属性指定分词器。刚才的例子指定了analyzer是指在索引使用english,默认为default index分词器standard分析器
  • index
    index属性指定是否索引。默认为true,设为false则不会进行索引,此时搜索无法获取。
  • store
    是否在source之外存储,每个文档索引后会在 ES中保存一份原始文档,存放在_source中,一般不需要设置为true,因为store文档中已经有一份原始文档了。

Keyword

Keyword目前已经取代了"index": false。Text文本字段在映射时要设置分词器,keyword字段为关键字字段,通常搜索keyword是按照整体搜索,所以创建keyword字段的索引时是不进行分词的,比如:邮政编码、 手机号码、身份证等。keyword字段通常用于过虑、排序、聚合等。

Number类型

Number字段和大多常见的字段一样。

  • long

一个有符号的 64 位整数,最小值为 -263,最大值为263-1。

  • integer

一个有符号的 32 位整数,最小值为 -232,最大值为232-1。

  • short

一个有符号的 16 位整数,最小值为-32,768,最大值为32,767。

  • byte

一个有符号的 8 位整数,最小值为-128,最大值为127。

  • double

双精度 64 位 IEEE 754 浮点数,限制为有限值。

  • float

单精度 32 位 IEEE 754 浮点数,限制为有限值。

  • half_float

半精度 16 位 IEEE 754 浮点数,限制为有限值。

  • scaled_float

由 a 支持的浮点数long,按固定double比例因子缩放。

如何更好的使用Number?

  • 尽量选择范围小的类型,提高搜索效率。
  • 对于浮点数尽量用比例因子,比如一个价格字段,单位为元,我们将比例因子设置为100这在ES中会按照分进行存储,映射如下:
"price": {
        "type": "scaled_float",
        "scaling_factor": 100
}

例如比例因子为100,假如我们输入的价格是23.45,则ES中会将23.45乘以100,得到2345,然后存储在ES中。
如果输入的价格是23.456,ES会将23.456乘以100再取一个接近原始值的数,得到2346,然后存储在ES中。

前段时间在看一本书叫做《高性能MySQL》,书中写道:在MySQL 5.0和更高版本,DECIMAL类型支持精确计算,对于一些银行金融业务,DECIMAL无疑是最好的选择。但在数据量比较大的时候,可以考虑使用BIGINT代替DECIMAL,将需要存储的货币单位根据小数的位数乘以相应的倍数即可。假设要存储财务数据精确到万分之一分,则可以把所有金额乘以一百万,然后将结果存储在BIGINT里,这样可以同时避免浮点存储计算不精确和DECIMAL精确计算代价高的问题。

比例因子就和此方法有异曲同工之处。

此外scaling_factor是scaled_float的一个附加参数,其它数字类型不支持。

Date类型

日期类型不用设置分词器,通常日期类型的字段用于排序。

  • 常用参数 format
    通过format设置日期格式
{
"properties": 
	{ 
	"timestamp": {
	"type": "date",
	"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd"
			 }
	} 
}

上面的设置允许date字段存储年月日时分秒、年月日及毫秒三种格式。

Object类型

Object类型是通过JSON形式来存储。

例如:

PUT /customer/store/1
{
  "address": {
    "country": "China",
    "province": "zhejiang",
    "city": "hangzhou"
  },
  "name": "jack",
  "age": 18,
  "birthday": "2021-01-01"
}

Nested类型

和Object类型一样,Nested类型包含了嵌套的表示。

例如:

{
    "customers": [
    { "age": 32, "name": "James Harder"},
	{ "age": 33, "name": "Stephen Curry"},
	{ "age": 33, "name": "Kevin Durant"}
 ] 
}

那么Object和Nested在底层是如何存储的?

上述的Object例子:

{
"name": [jack]
"age": [18]
"birthday": [2021-01-01]
"address.country": [China],
"address.province": [zhejiang],
"address.city":  [hangzhou]
}

上述的Nested例子:

{
	"customers.age": [32,33,33],
	"customers.name": [James,Harder,Stephen,Curry,Kevin,Durant]
}

ES会进行分词然后通过数组的格式进行存储,关于分词,之后会在文章中进行介绍。

感谢阅读!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值