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] |
float | 32位单精度浮点数 |
double | 64位双精度浮点数 |
half_float | 16位半精度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_range | 32位单精度浮点型 |
double_range | 64位双精度浮点型 |
date_range | 64位整数, 毫秒计时 |
ip_range | IP值的范围, 支持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(映射,分析)
Elastic Search 浅浅认识 快速使用 keyword 和 text 的区别之处 spring boot 集成案例 es 增删改查