环境:
Elasticsearch: 6.2.2
Kibana: 6.2.2
os: centos 7
原文链接:https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html
原文链接:https://www.elastic.co/guide/en/elasticsearch/reference/current/removal-of-types.html
Mapping是用来定义document是什么样子以及它包含的字段的怎么去排序,怎么去索引,Mapping能定义一下方面:
a、哪一个string字段需要被视为全文本字段。
b、哪一个字段包含数字、日期、逻辑等。
c、是否文档中的字段需要被索引到_all 索引中。
d、日期字段的格式
e、用户动态添加字段的默认规则
1、Mapping Type
每一个index都有一个Mapping来定义该index怎样去索引,需要注意的是,大体概念我们可以这样理解ES中的index和Mapping Type,index 对应SQL DB中的database,Mapping Type对应 SQL DB中的table,但是又不完全一样,因为在SQL DB中,不同table中的字段名称可以重复,但是定义可以不一样,再ES中却不可以存在这种情况,因为ES是基于Lucene,在ES映射到Lucene时,同一个index下面的不同mapping的同一字段名映射是同一个的,也就意味着,再不同的mapping中,相同字段名的类型也要保持一致。
再ES 6.x中支持的type类型有:
参考:https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-types.html#_geo_datatypes
基础类型:
字符类型:
text、keyword
数字类型:
long、integer、short、byte、double、float、half_float、sacled_float
日期类型:
date
布尔类型:
boolean
字节型:
binary
范围型:
integer_range、float_range、long_range、double_rang、date_range
复杂类型:
数组类型(array):数组类型不需要明确声明内容类型
类类型(object):只针对于一个json类型的类。
嵌套类型(nested):嵌套json数组
地标类型:
地标坐标(geo-point):经纬度坐标
地标形状类型(geo_shape):复杂的图形
特殊类型:
ip类型(ip):IPv4、IPv6
自动完成类型(completion):会自动完成补全的类型.
令牌统计类型(token_count):统计字符串中的数量
哈希计算类型(murmur3):在创建索引的时候就会计算出哈希值并存储
渗透类型(percolator):接受从query-dsl来的请求
联合类型(join):定义同一个index中,document的子父的关系
Multi-Fields
有时候我们搜索的时候需要把一个字段的类型定义为full-text,当排序的时候又需要把它当做keyword类型,这个时候我们就需要使用Multi-Fields类型了,使用参考,可以使用fields来对大部分类型做Multi-Fields处理。
格式如下:
"properties": {
"city": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
}
}
2、各个类型使用详细说明
A、数组
在ES中,数组可以为空,但是此时会被视为NULL,并且数组中的数据类型并且统一,比如[“stringData”,2222]这种是不允许的,例如可以一下格式:
- 字符数组: [
"one"
,"two"
] - 整数数组: [
1
,2
] - 数组型数组: [
1
, [2
,3
]] which is the equivalent of [1
,2
,3
] - 类数组: [
{ "name": "Mary", "age": 12 }
,{ "name": "John", "age": 10 }
]
注意:类数组中,类里面的数据是不能被搜索到的,如果想要搜索到内部内容,需要使用嵌套格式。
PUT my_index/_doc/1 { "message": "some arrays in this document...", "tags": [ "elasticsearch", "wow" ], "lists": [ { "name": "prog_list", "description": "programming list" }, { "name": "cool_list", "description": "cool stuff list" } ] }
B、二进制类型
二进制类型接受的是一个BASE64过后的字符串,默认改字段是不能被排序和搜索到的。
注意:Base64的字符串不能包含换行符\n。
fields参数:
doc_values:取值true、false,当该字段为true时,该字段则可以被排序、查询、脚本处理等。
strore:取值true、false,标记该字段是否存储在_source中。
PUT my_index { "mappings": { "_doc": { "properties": { "name": { "type": "text" }, "blob": { "type": "binary" } } } } } PUT my_index/_doc/1 { "name": "Some binary blob", "blob": "U29tZSBiaW5hcnkgYmxvYg==" }
C、范围类型
原文地址:https://www.elastic.co/guide/en/elasticsearch/reference/current/range.html
示例,添加一个整数范围和一个时间范围的Mapping
PUT range_index
{
"mappings": {
"_doc": {
"properties": {
"expected_attendees": {
"type": "integer_range"
},
"time_frame": {
"type": "date_range",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
}
}
}
PUT range_index/_doc/1
{
"expected_attendees" : {
"gte" : 10,
"lte" : 20
},
"time_frame" : {
"gte" : "2018-10-31 12:00:00",
"lte" : "2018-11-01"
}
}
然后执行搜索:
GET range_index/_search
{
"query" : {
"term" : {
"expected_attendees" : {
"value": 12
}
}
}
}
结果如下:
{
"took": 13,
"timed_out": false,
"_shards" : {
"total": 2,
"successful": 2,
"skipped" : 0,
"failed": 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
{
"_index" : "range_index",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"expected_attendees" : {
"gte" : 10, "lte" : 20
},
"time_frame" : {
"gte" : "2018-10-31 12:00:00", "lte" : "2018-11-01"
}
}
}
]
}
}
再来一个时间范围查找的示例:查找
GET range_index/_search
{
"query" : {
"range" : {
"time_frame" : {
"gte" : "2018-10-31",
"lte" : "2018-11-01",
"relation" : "within"
}
}
}
}
relation取值:within、contains、intersects
data_rang的fields:
coerce:尝试将字符串转换为数值,并且进行截取操作。取值true(默认值)、false。
boost: Mapping field-level query time boosting(没明白什么意思),要求一个float类型的数字,默认是1.0。
index:该字段是否被搜索到,取值true(默认值)、false。
store:该字段是否存储在_source中,取值true、false(默认值)。
D、boolean 类型
取值:true、“true”、“false”、false
注意在脚本中,该类型被视为1、0
Fields设置:
doc_value: 该字段是否被跨行存储在硬盘上,这样可以用来做排序等操作,取值true(默认值)、false。
boost: Mapping field-level query time boosting(没明白什么意思),要求一个float类型的数字,默认是1.0。
index:该字段是否被搜索到,取值true(默认值)、false。
store:该字段是否存储在_source中,取值true、false(默认值)。
null_value: 是否可以为null值,如果为null则视为空值。
E、date类型
json是没有时间日期类型的,所以在ES中时间日期来源有:
- 包含格式化之后的日期的字符串比如“2018-03-16”、“2018-03-16 12:23:46”
- 毫秒时间戳
- 秒时间戳
实时上,时间日期会被转换为UTC时间然后毫秒时间戳存储,默认的时间格式为:"strict_date_optional_time||epoch_millis"
另外还可以自定义格式。再ES中提供的默认格式有很多可以参考详细说明的基础格式。
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 } GET my_index/_search { "sort": { "date": "asc"} }
还可以使用多个格式器来格式化时间,多个格式器之间使用||做分格,如下:
PUT my_index { "mappings": { "_doc": { "properties": { "date": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" } } } } }
Fields设置:
doc_value: 该字段是否被跨行存储在硬盘上,这样可以用来做排序等操作,取值true(默认值)、false。
index:该字段是否被搜索到,取值true(默认值)、false。
store:该字段是否存储在_source中,取值true、false(默认值)。
null_value: 是否可以为null值,如果为null则视为空值。
format:格式化日期的格式默认是"strict_date_optional_time||epoch_millis"
ignore_malformed:是否忽略畸形不可格式化的格式,如果为true,畸形的被忽略,如果为false,遇到畸形输入则会抛出一个异常并且抛弃所有数据。
locale:使用本地来格式化时间,默认是ROOT local
F、Geo-Point类型
原文地址:https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-point.html
geo-point类型接受一个latitude-longitude数据对儿,可以用来:
- 用来查在在一个bounding_box范围内 ,或者离中心点的距离,或者一个多边形区域
- 在地理上聚合或者以到一个中心点的距离来聚合。
- 通过距离来排序
- 计算距离相关计算
下面给出几种数据插入方式:
PUT my_index { "mappings": { "_doc": { "properties": { "location": { "type": "geo_point" } } } } } PUT my_index/_doc/1 { "text": "Geo-point as an object", "location": { "lat": 41.12, "lon": -71.34 } } PUT my_index/_doc/2 { "text": "Geo-point as a string", "location": "41.12,-71.34" } PUT my_index/_doc/3 { "text": "Geo-point as a geohash", "location": "drm3btev3e86" } PUT my_index/_doc/4 { "text": "Geo-point as an array", "location": [ -71.34, 41.12 ] }
文档3中使用的是geohash的经纬度表示方法的值。
文档2中使用的是"lat,lon"
文档4使用的是[ lon, lat]格式
Fields设置:
ignore_malformed:是否忽略畸形不可格式化的格式,如果为true,畸形的被忽略,如果为false,遇到畸形输入则会抛出一个异常并且抛弃所有数据。
H、Geo-Shape类型
原文地址:https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-shape.html
原文地址:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-shape-query.html
Geo-mapping的设置:
tree:PrefixTree的选择,取值geohash(默认)、quadtree分别对应GeohashPrefixTree、QuadPrefixTree.
precision:精度选择,可以用来替代tree_levels设置,取值in, inch, yd, yard, mi, miles, km, kilometers, m,meters(默认), cm,centimeters, mm, millimeters。
tree_levels:定义PrefixTree最大的层级,平常都是用precision来替代这个设置,这个可以来控制图形的描绘精度,并且控制图形的索引点数,默认是50m
strategy:定义了当索引或者查询的时候的方法策略,这个也会影响容量大小,所以我们一般都让ES自动设置,取值有两个recursive(默认) 和 term,其中term策略只支持点类型(point type),points_only参数此时会自动设置为true,Recursive支持所有的图形形状,可以参考:https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-shape.html#prefix-trees,详细说明
distance_error_pct:定义了PrefixTree的命中精度,默认为0.025(2.5%),最大取值0.5。
orientation:这个定义了怎样去识别多边形的顶点,这里面定义了两套参考系统(Right-hand or Left-hand),对应值分别为:1. Right-hand rule: right, ccw, counterclockwise(默认值), 2. Left-hand rule: left, cw, clockwise.
points_only:取值true、false(默认值),该参数不支持多边形。
ignore_malformed:取值true、false(默认值)。异性数据处理,为fasle时,当出现异性图形是会抛出异常。
Prefix trees
Prefix trees影响了ES中图形的索引表现,在这个算法里面,图形被转化为一些列哈希过后的数据,trees里面使用两种种坐标系来提高映射到实际中的精准度,这个也就是为了提高地图在高维空间的一些细节。
Prefix trees提供了两种坐标系:
GeohashPrefixTree:使用geohash来处理坐标空间, Geohashes中使用32位的字符串来表示空间坐标,所以字符串越长,每增加一个字符串,将要增加5bit的精准度 ,每个Geohashes表示一个矩形区域,并且它内部还划分为32个子矩形区域,再ES中,最高精准界级别是24.
QuadPrefixTree:使用quadTree来处理坐标空间,和Geohashes也是相似的,它在经纬度的hash值中插入了一些字节,一个tree level 再这里面代表了2 bits,此空间中最大的等级是50