ESElasticsearch之数据类型

Posted 逆流°只是风景-bjhxcc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ESElasticsearch之数据类型相关的知识,希望对你有一定的参考价值。

文章目录

1、Mapping

1.1 Mapping的作用

ES中的Mapping 类似于数据库中的表结构定义 schema,它有以下几个作用:

  • 定义索引中的字段的名称
  • 定义字段的数据类型,比如字符串、数字、布尔等
  • 定义字段的属性,比如设置某个字段为要不要被分词,要不要被索引等

在 ES 早期版本,一个索引下是可以有多个 Type ,从 7.0 开始,一个索引只有一个 Type,也就是说不需要在 Mapping 指定 type 信息。

一个简单的例子如下:


    "mappings":
        "type_name":                           //type名称
            "dynamic": "strict",      //是否可以动态添加字段
            "properties":                      
                "name":                            //字段名
                    "type":"keyword"    //字段的数据类型
                ,
                "message":
                    "type":"text"
                ,
                "age":
                    "type":"integer"
                
            
        
    

mapping中字段类型一旦设定后禁止直接修改。因为Lucene实现的倒排索引生成后不允许修改,除非重建索引映射,然后做reindex操作。

1.2 Dynamic Mapping

Dynamic Mapping 机制使我们不需要手动定义 Mapping,ES 会自动根据文档信息来判断字段合适的类型,但是有时候也会推算的不对,比如地理位置信息有可能会判断为 Text,当类型如果设置不对时,会导致一些功能无法正常工作,比如 Range 查询。

ES 类型的自动识别是基于 JSON 的格式,如果输入的是 JSON 是字符串且格式为日期格式,ES 会自动设置成 Date 类型;当输入的字符串是数字的时候,ES 默认会当成字符串来处理,可以通过设置来转换成合适的类型;如果输入的是 Text 字段的时候,ES 会自动增加 keyword 子字段,还有一些自动识别如下表所示:

JSON 类型Elasticsearch 类型
字符串匹配日期格式设置成 Date;设置数字设置为 float 或者 long,该选项默认关闭;设置为 Text, 并增加 keyword 子字
布尔值boolean
浮点数float
整数long
对象Object
数组由第一个非空数值的类型所决定
空值忽略
//写入文档
PUT mapping_test/_doc/1

  "firstName":"Lee",
  "lastName":"Crazy",
  "loginDate":"2020-08-26T21:08:48"


//查看Mapping 文件
GET mapping_test/_mapping

  "mapping_test" : 
    "mappings" : 
      "properties" : 
        "firstName" : 
          "type" : "text",
          "fields" : 
            "keyword" : 
              "type" : "keyword",
              "ignore_above" : 256
            
          
        ,
        "lastName" : 
          "type" : "text",
          "fields" : 
            "keyword" : 
              "type" : "keyword",
              "ignore_above" : 256
            
          
        ,
        "loginDate" : 
          "type" : "date"
        
      
    
  

//dynamic mapping 推断字符的类型
PUT mapping_test/_doc/1

  "uid":"123",
  "isVip": false,
  "isAdmin":"true",
  "age": 18,
  "heigh" : 180


//返回结果

  "mapping_test" : 
    "mappings" : 
      "properties" : 
        "age" : 
          "type" : "long"
        ,
        "heigh" : 
          "type" : "long"
        ,
        "isAdmin" : 
          "type" : "text",
          "fields" : 
            "keyword" : 
              "type" : "keyword",
              "ignore_above" : 256
            
          
        ,
        "isVip" : 
          "type" : "boolean"
        ,
        "uid" : 
          "type" : "text",
          "fields" : 
            "keyword" : 
              "type" : "keyword",
              "ignore_above" : 256
            
          
        
      
    
  

Dynamic Mapping 机制由参数dynamic控制,的可选值有三个:

  • true:允许自动将检测到的新字段加到映射中(默认的)
  • false: 不允许自动新增字段,文档可以写入,但无法对字段进行搜索等操作,不会添加在映射中。
  • strict:文档不能写入,写入会报错

1.3 字段控制参数

在字段层面也有很多可以设置的参数,下面只列举几个重要的,其余可以参考官网的说明。

1.3.1 index

控制当前字段是否被索引。默认为 true。如果设置成 false,该字段不可被搜索。


  "mappings" : 
    "properties" : 
      "firstName" : 
        "type" : "text"
      ,
      "lastName" : 
        "type" : "text"
      ,
      "mobile" : 
        "type" : "text",
        "index": false
      
    
  

1.3.2 Index Options

四种不同级别的 Index Options 配置,可以控制倒排索引记录的内容

  • docs: 记录 doc id
  • freqs: 记录 doc id 和 term frequencies
  • positions: 记录 doc id /term frequencies /term position
  • offsets: 记录doc id / term frequencies / term posistion / character offects

Text 类型默认记录 postions,其他默认为 docs。

记录内容越多,占用存储空间越大。

1.3.3 null_value

需要对 NULL 值实现搜索,只有 Keyword 类型支持设定 Null_Value。

//设置Mapping
PUT users

  "mappings" : 
    "properties" : 
      "firstName" : 
        "type" : "text"
      ,
      "lastName" : 
        "type" : "text"
      ,
      "mobile" : 
        "type" : "keyword", //这个如果是text 无法设置为空
        "null_value": "NULL"
      
    
  


//添加记录
PUT users/_doc/2

"firstName":"Li",
"lastName": "Sunke",
"mobile": null


//搜索空值
GET users/_search?q=mobile:NULL
"_source" : 
        "firstName" : "Li",
        "lastName" : "Sunke",
        "mobile" : null
      

1.3.4 copy_to

_all 在ES 7 中已经被 copy_to 所替代。

copy_to 将字段的数值拷贝到目标字段,实现类似 _all 的作用,用于满足一些特定的搜索需求,类似于数据库 title like “%a%” or title2 like “%a%”。

//设置Mapping
PUT users

"mappings": 
  "properties": 
    "firstName":
      "type": "text",
      "copy_to": "fullName"
    ,
    "lastName":
      "type": "text",
      "copy_to": "fullName"
    
  



//添加记录
PUT users/_doc/1

"firstName":"Kobe",
"lastName": "Bryant"


//使用fullName查询
GET users/_search?q=fullName:(Kobe Bryant)

//_source中不会有fullName字段

"_index" : "users",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : 
  "firstName" : "Kobe",
  "lastName" : "Bryant"


2、数据类型

ES支持的数据类型可以做如下分类:

2.1 核心数据类型

2.1.1 字符串类型

2.1.1.1 text
当一个字段需要用于全文搜索(会被分词),比如产品名称、产品描述信息,就应该使用text类型。

text类型的字段不能用于排序, 也很少用于聚合。


    "mappings":
        "blog":
            "properties":
                "summary":
                    "type":"text",
                    "index":"true"
                
            
        
    

2.1.1.2 keyword
当一个字段需要按照精确值进行过滤、排序、聚合等操作时,就应该使用keyword类型。

keyword与text最大的区别就是不会被分词,而是当做一个整体来索引。


    "mappings":
        "blog":
            "properties":
                "tags":
                    "type":"keyword",
                    "index":"true"
                
            
        
    

2.1.2 数字类型

类型说明
byte有符号的8位整数, 范围: [-128 ~ 127]
short有符号的16位整数, 范围: [-32768 ~ 32767]
integer有符号的32位整数, 范围: [−2^31 ~ 2^31-1]
long有符号的64位整数, 范围: [−2^63 ~ 2^63-1]
float32位单精度浮点数
double64位双精度浮点数
half_float16位半精度IEEE 754浮点类型
scaled_float缩放类型的的浮点数, 比如price字段只需精确到分, 57.34缩放因子为100, 存储结果为5734
  • 尽可能选择范围小的数据类型,字段的长度越短,索引和搜索的效率越高
  • 优先考虑使用带缩放因子的浮点类型

    "mappings": 
        "book": 
            "properties": 
                "name": "type": "text",
                "quantity": "type": "integer",  // integer类型
                "price": 
                    "type": "scaled_float",       // scaled_float类型
                    "scaling_factor": 100
                
            
        
    

2.1.3 日期类型

2.1.3.1 date

JSON没有日期数据类型, 所以在ES中, 日期可以是:

  • 包含格式化日期的字符串, “2020-08-26”, 或"2020/08/26 12:00:00"
  • 代表时间毫秒数的长整型数字
  • 代表时间秒数的整数
PUT my_index

  "mappings": 
    "_doc": 
      "properties": 
        "date": 
          "type": "date" 
        
      
    
  


PUT my_index/_doc/1
 "date": "2015-01-01"  

PUT my_index/_doc/2
 "date": "2015-01-01T12:10:30Z"  

PUT my_index/_doc/3
 "date": 1420070400001  

同时ES的date类型允许我们规定格式:

# 规定格式如下: || 表示或者
PUT my_index

  "mappings": 
    "_doc": 
      "properties": 
        "date": 
          "type":   "date",
          "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
        
      
    
  

一旦我们规定了格式,如果新增数据不符合这个格式,ES将会报错。

2.1.3.2 date_nanos

ES 7新增的时间类型,可精确到纳秒,用法类似date。

2.1.4 布尔类型

可以接受表示真、假的字符串或数字:

  • 真值: true, “true”, “on”, “yes”, “1”…
  • 假值: false, “false”, “off”, “no”, “0”, “”(空字符串), 0.0, 0

2.1.5 二进制类型

二进制类型是Base64编码字符串的二进制值,不以默认的方式存储,且不能被搜索。

有2个设置项:

  • doc_values: 该字段是否需要存储到磁盘上,方便以后用来排序、聚合或脚本查询。接受true和false(默认)
  • store: 该字段的值是否要和_source分开存储、检索,意思是除了_source中, 是否要单独再存储一份。接受true或false(默认).

使用示例:

// 添加映射
PUT website

    "mappings": 
        "blog": 
            "properties": 
                "blob": "type": "binary"   // 二进制
            
        
    


// 添加数据
PUT website/blog/1

    "title": "Some binary blog",
    "blob": "hED903KSrA084fRiD5JLgY=="

注意: Base64编码的二进制值不能嵌入换行符\\n, 逗号(0x2c)等符号。

2.1.6 范围类型

range类型支持以下几种:

类型范围
integer_range−2^31 ~ 2^31−1
long_range−2^63 ~ 2^63−1
float_range32位单精度浮点型
double_range64位双精度浮点型
date_range64位整数, 毫秒计时
ip_rangeIP值的范围, 支持IPV4和IPV6, 或者这两种同时存在

添加映射:

PUT company

    "mappings": 
        "department": 
            "properties": 
                "expected_number":   // 预期员工数
                    "type": "integer_range"
                ,
                "time_frame":        // 发展时间线
                    "type": "date_range", 
                    "format": "yyyy-MM-dd HH:mm:ss"
                ,
                "ip_whitelist":      // ip白名单
                    "type": "ip_range"
                
            
        
    

添加数据:

PUT company/department/1

    "expected_number" : 
        "gte" : 10,
        "lte" : 20
    ,
    "time_frame" :  
        "gte" : "2020-08-01 12:00:00", 
        "lte" : "2020-09-01 12:00:00"
    , 
    "ip_whitelist": "192.168.0.0/16"

查询数据:

GET company/department/_search

    "query": 
        "term": 
            "expected_number": 
                "value": 12
            
        
    


GET company/department/_search

    "query": 
        "range": 
            "time_frame": 
                "gte": "2020-08-10 12:00:00",
                "lte": "2020-08-20 12:00:00",
                "relation": "within" 
            
        
    

2.2 复杂数据类型

2.2.1 数组类型

在Elasticsearch中,数组不需要专用的字段数据类型。默认情况下,任何字段都可以包含零个或多个值。

数组中所有的值必须是同一种数据类型, 不支持混合数据类型的数组:

  • 字符串数组: [“one”, “two”]
  • 整数数组: [1, 2]
  • 由数组组成的数组: [1, [2, 3]], 等价于[1, 2, 3]
  • 对象数组: [“name”: “Tom”, “age”: 20, “name”: “Jerry”, “age”: 18]

2.2.2 对象类型

JSON文档是分层的:文档可以包含内部对象,内部对象也可以包含内部对象。

添加示例:

PUT employee/developer/1

    "name": "Winner",
    "address": 
        "region": "China",
        "location": "province": "ZheJiang", "city": "HuangZhou"
    

存储方式:


    "name":                       "Winner",
    "address.region":             "China",
    "address.location.province":  "ZheJiang", 
    "address.location.city":      "HuangZhou"

文档的映射结构类似为:

PUT employee

    "mappings":
        "developer":
            "properties":
                "name":
                    "type":"text",
                    "index":"true"
                ,
                "address":
                    "properties":
                        "region":
                            "type":"keyword",
                            "index":"true"
                        ,
                        "location":
                            "properties":
                                "province":
                                    "type":"keyword",
                                    "index":"true"
                                ,
                                "city":
                                    "type":"keyword",
                                    "index":"true"
                                
                            
                        
                    
                
            
        
    

2.2.3 嵌套类型

嵌套类型是对象数据类型的一个特例,可以让array类型的对象被独立索引和搜索。

先来看下对象数据类型是怎么存储的。

添加数据:

PUT game_of_thrones/role/1

    "group":"stark",
    "performer":[
        
            "first":"John",
            "last":"Snow"
        ,
        
            "first":"Sansa",
            "last":"Stark"
        
    ]

内部存储结构:


    "group":"stark",
    "performer.first":[
        "john",
        "sansa"
    ],
    "performer.last":[
        "snow",
        "stark"
    ]

可以看出,user.first和user.last会被平铺为多值字段,这样一来,John和Snow之间的关联性丢失了,在查询时, 可能出现John Stark的结果。

嵌套数据类型可以解决关联性丢失的问题。嵌套对象实质是将每个对象分离出来,作为隐藏文档进行索引。

创建映射:

PUT game_of_thrones

    "mappings":
        "role":
            "properties":
                "performer":
                    "type":"nested"
                
            
        
    

添加数据:

PUT game_of_thrones/role/1

    "group":"stark",
    "performer":[
        
            "first":"John",
            "last":"Snow"
        ,
        
            "first":"Sansa",
            "last":"Stark"
        
    ]

检索数据:

GET game_of_thrones/_search

    "query":
        "nested":
            "path":"performer",
            "query":
                "bool":
                    "must":[
                        
                            "match":
                                "performer.first":"John"
                            
                        ,
                        
                            "match":
                                "performer.last":"Snow"
                            
                        
                    ]
                
            
        
    

2.3 空间数据类型

2.3.1 地理点类型

地理点类型用于存储地理位置的经纬度对,可用于:

  • 查找一定范围内的地理点;
  • 通过地理位置或相对某个中心点的距离聚合文档;
  • 将距离整合到文档的相关性评分中;
  • 通过距离对文档进行排序.

添加映射:

PUT employee

    elasticSearch-mappings(映射,分析)

Elasticsearch 学习笔记1 入门

ElasticSearch之映射常用操作

Elastic Search 浅浅认识 快速使用 keyword 和 text 的区别之处 spring boot 集成案例 es 增删改查

日志收集之--将Kafka数据导入Elastic

Elasticsearch 入门简介