版本:Elasticsearch 6.2.4。
Mapping相似于数据库中的表结构定义,主要做用以下:php
Mapping完整的内容能够分为四部份内容:html
若是没有手动设置Mapping,Elasticsearch默认会自动解析出类型,且每一个字段以第一次出现的为准。java
下面咱们先看一下Elasticsearch默认建立的Mapping是什么样的。 数据库
首先咱们建立一个索引:segmentfault
PUT /user/
查询索引信息:数组
GET /user
结果:app
{ "user": { "aliases": {}, "mappings": {}, "settings": { "index": { "creation_date": "1540044686190", "number_of_shards": "5", "number_of_replicas": "1", "uuid": "_K5b8w7jRiuthf7QeQZhdw", "version": { "created": "5060299" }, "provided_name": "user" } } } }
增长一条数据:elasticsearch
PUT /user/doc/1 { "name":"Allen Yer", "job":"php", "age":22 } PUT /user/doc/2 { "name":"Allen Yer", "job":0, "age":22 }
查询数据是否新增成功:ide
GET /user/doc/_count
结果:post
{ "count": 2, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 } }
count为2,说明新增成功。而后咱们查询下 mapping :
{ "user": { "mappings": { "doc": { "properties": { "age": { "type": "long" }, "job": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "name": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } } } } }
发现自动为每一个字段设置了类型:
name.keyword
字段,keyword
类型;job.keyword
字段,keyword
类型;虽然第二次数据新增是数字类型,但仍是以第一次为主;你们能够把索引删掉,将新增数据调整为先新增第2条,再新增第一条,发现报错了:
DELETE /user PUT /user/doc/2 { "name":"Allen Yer", "job":0, "age":22 } PUT /user/doc/1 { "name":"Allen Yer", "job":"php", "age":22 }
报错:
{ "error": { "root_cause": [ { "type": "mapper_parsing_exception", "reason": "failed to parse [job]" } ], "type": "mapper_parsing_exception", "reason": "failed to parse [job]", "caused_by": { "type": "number_format_exception", "reason": "For input string: \"php\"" } }, "status": 400 }
也能说明以第一次为主以字段第一次的值类型为准。这也说明了默认建立mapping可能不是咱们想要的,这就须要手动建立mapping,好处有:
此次咱们删掉mapping,并手动建立一个:
DELETE /user PUT /user/ { "mappings": { "doc": { "properties": { "name": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "age": { "type": "long", "index": false }, "job": { "type": "keyword" }, "intro":{ "type":"text" }, "create_time": { "type": "date", "format": "epoch_second" } } } } }
字段类型说明:
注意:mapping生成后是不容许修改(包括删除)的。因此须要提早合理的的定义mapping。
Elasticsearch支持文档中字段的许多不一样数据类型:
有text
和 keyword
2种 。其中 text
支持分词,用于全文搜索;keyword
不支持分词,用于聚合和排序。在旧的ES里这两个类型由string
表示。
若是安装了IK分词插件,咱们能够为text
类型指定IK分词器。通常来讲,对于字符串类型,若是:
1) 模糊搜索+精确匹配,通常是name或者title字段:
"name": { "type": "text", "analyzer": "ik_smart", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }
2) 模糊搜索,通常是内容详情字段:
"content": { "type": "text", "analyzer": "ik_smart" }
3) 精确匹配:
"name": { "type": "keyword" }
4) 不须要索引:
"url": { "type": "keyword", "index": false }
支持 long,integer,short,byte,double,float,half_float,scaled_float。具体说明以下:
带符号的64位整数,其最小值为-2^63
,最大值为(2^63)-1
。
带符号的32位整数,其最小值为-2^31
,最大值为(23^1)-1
。
带符号的16位整数,其最小值为-32,768,最大值为32,767。
带符号的8位整数,其最小值为-128,最大值为127。
双精度64位IEEE 754浮点数。
单精度32位IEEE 754浮点数。
半精度16位IEEE 754浮点数。
缩放类型的的浮点数。需同时配置缩放因子(scaling_factor)一块儿使用。
对于整数类型(byte,short,integer和long)而言,咱们应该选择这是足以使用的最小的类型。这将有助于索引和搜索更有效。
对于浮点类型(float、half_float和scaled_float),-0.0
和+0.0
是不一样的值,使用term
查询查找-0.0
不会匹配+0.0
,一样range
查询中上边界是-0.0
不会匹配+0.0
,下边界是+0.0
不会匹配-0.0
。
其中scaled_float
,好比价格只须要精确到分,price
为57.34
的字段缩放因子为100
,存起来就是5734
。优先考虑使用带缩放因子的scaled_float
浮点类型。
示例:
PUT my_index { "mappings": { "_doc": { "properties": { "status": { "type": "byte" }, "year": { "type": "short" }, "id": { "type": "long" }, "price": { "type": "scaled_float", "scaling_factor": 100 } } } } }
类型为 date
。
JSON自己是没有日期类型的,所以Elasticsearch中的日期能够是:
在Elasticsearch内部,日期类型会被转换为UTC(若是指定了时区)并存储为long类型表示的毫秒时间戳。
日期类型可使用使用format
自定义,默认缺省值:"strict_date_optional_time||epoch_millis"
:
"postdate": { "type": "date", "format": "strict_date_optional_time||epoch_millis" }
format
有不少内置类型,这里列举部分说明:
通用的ISO日期格式,其中日期部分是必需的,时间部分是可选的。例如 "2015-01-01"或"2015/01/01 12:10:30"。
13位毫秒时间戳
10位普通时间戳
其中strict_
开头的表示严格的日期格式,这意味着,年、月、日部分必须具备前置0。
更多日期格式详见: https://www.elastic.co/guide/...
固然也能够自定义日期格式,例如:
"postdate":{ "type":"date", "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd" }
注意:若是新文档的字段的值与format里设置的类型不兼容,ES会返回失败。示例:
PUT my_index { "mappings": { "_doc": { "properties": { "date": { "type": "date", "format":"epoch_millis" } } } } } PUT my_index/_doc/1 { "date":1543151405000 } PUT my_index/_doc/2 { "date":1543151405 } PUT my_index/_doc/3 { "date":"2018-11-25 21:10:43" } GET my_index/_doc/_search
第3条数据插入失败,由于只接受长整数的时间戳,字符串类型的日期是不匹配的。第2条的值只有10位数,虽然值是不正确的,可是在epoch_millis
的取值范围内,因此也是成功的。
类型为 boolean
。
类型为 binary
。
integer_range,float_range,long_range,double_range,date_range
在ElasticSearch中,没有专门的数组(Array)数据类型,可是,在默认状况下,任意一个字段均可以包含0或多个值,这意味着每一个字段默认都是数组类型,只不过,数组类型的各个元素值的数据类型必须相同。在ElasticSearch中,数组是开箱即用的(out of box),不须要进行任何配置,就能够直接使用。,例如:
字符型数组: [ "one", "two" ]
整型数组:[ 1, 2 ]
数组型数组:[ 1, [ 2, 3 ]]
等价于[ 1, 2, 3 ]
object 对于单个JSON对象。JSON天生具备层级关系,文档能够包含嵌套的对象。
nested 对于JSON对象的数组
geo_point 对于纬度/经度点
geo_shape 对于像多边形这样的复杂形状
ip 用于IPv4和IPv6地址
completion 提供自动完成的建议
token_count 计算字符串中的标记数
murmur3 在索引时计算值的哈希值并将它们存储在索引中
接受来自query-dsl的查询
为同一索引中的文档定义父/子关系
为不一样目的以不一样方式索引相同字段一般颇有用。例如,string能够将字段映射为text用于全文搜索的keyword字段,以及用于排序或聚合的字段。或者,您可使用standard分析仪, english分析仪和 french分析仪索引文本字段。
该字段用于在没有指定具体字段的状况下进行模糊搜索,能够搜索所有字段的内容。
原理是将全部字段的内容视为字符串,拼在一块儿放在一个_all
字段上,但这个字段默认是不被存储的,能够被搜索。在query_string
与 simple_query_string
查询(Kibana搜索框用的这种查询方式)默认也是查询_all
字段。
6.x
版本被默认关闭。
相关设置:
PUT my_index { "mappings": { "my_type": { "_all": { "enabled": true, "store": false }, "properties": {} } }, "settings": { "index.query.default_field": "_all" } }
上述配置在5.x
版本是默认配置:
_all
字段_all
字段_all
字段若是从CPU性能及磁盘空间考虑,能够考虑能够彻底禁用或基于每一个字段自定义_all
字段。
假设_all
字段被禁用,则URI搜索请求、 query_string
和simple_query_string
查询将没法将其用于查询。咱们能够将它们配置为其余字段:经过定义 index.query.default_field
属性。
这个字段用于存储原始的JSON文档内容,自己不会被索引,可是搜索的时候被返回。若是没有该字段,虽然还能正常搜索,可是返回的内容不知道对应的是什么。
示例:
GET /user/doc/_search?q=name
结果:
{ "took": 4, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 1, "max_score": 0.2876821, "hits": [ { "_index": "user", "_type": "doc", "_id": "1", "_score": 0.2876821, "_source": { "name": "this is test name", "age": 22, "job": "java", "intro": "the intro can not be searched by singal", "intro2": "去朝阳公园", "create_time": 1540047542 } } ] } }
搜索结果就包含_source
字段,存储的是原始文档内容。若是被禁用,只知道有匹配内容,可是没法知道返回的是什么。因此须要谨慎关闭该字段。
若是想禁用该字段,能够在建立Mapping的时候,设置_:
{ "mappings": { "_doc": { "_source": { "enabled": false } } } }
ElasticSearch里面有 index 和 type 的概念:index称为索引,type为文档类型,一个index下面有多个type,每一个type的字段能够不同。这相似于关系型数据库的 database 和 table 的概念。
可是,ES中不一样type下名称相同的filed最终在Lucene中的处理方式是同样的。因此后来ElasticSearch团队想去掉type,因而在6.x版本为了向下兼容,一个index只容许有一个type。
该字段再在6.0.0中弃用。在Elasticsearch 6.x 版本中建立的索引只能包含单个type。在5.x中建立的含有多个type的索引将继续像之前同样在Elasticsearch 6.x中运行。type 将在Elasticsearch 7.0.0中彻底删除。
详见:https://www.elastic.co/guide/...
一、Mapping | Elasticsearch Reference [6.4] | Elastic
https://www.elastic.co/guide/...
二、Elasticsearch 6.x Mapping设置 - 小旋锋
https://mp.weixin.qq.com/s/pB...
三、整理的es中的mapping方面的内容 - 辛星,前进的路上. - CSDN博客
https://blog.csdn.net/xinguim...
四、[译]ElasticSearch数据类型--string类型已死, 字符串数据永生 - 牧曦之晨 - SegmentFault 思否
https://segmentfault.com/a/11...
五、ElasticSearch的_all域 | 学步园
https://www.xuebuyuan.com/205...
六、图解Elasticsearch中的_source、_all、store和index属性 - 1.01^365=37.78 (Lucene、ES、ELK开发交流群: 370734940) - CSDN博客
https://blog.csdn.net/napoay/...
七、Elasticsearch - 自动检测及动态映射Dynamic Mapping - 上善若水,水善利万物而不争。 - CSDN博客
https://blog.csdn.net/xifeiji...
八、Field datatypes | Elasticsearch Reference [6.2] | Elastic
https://www.elastic.co/guide/...