Elasticsearch的Mapping,定义了索引的结构,相似于关系型数据库的Schema。Elasticsearch的Setting定义中定义分片和副本数以及搜索的最关键组件,即:Analyzer,也就是分析器。php
1、Dynamic Mapping及经常使用字段类型
mapping 的定义
Mapping相似于关系型数据库的Schema,主要包含如下内容:html
- 定义索引中字段的名称
- 定义字段的数据类型,如:字符串、数字、boolean等
- 可对字段设置倒排索引的相关配置,如是否须要分词,使用什么分词器
从7.x开始,一个Mapping只属于一个索引的typepython
- 每一个文档属于一个type
- 一个type有且仅有一个Mapping定义
- 从7.x开始,不须要在Mapping中指定type信息,默认type为
_doc
经常使用字段类型
在Elasticsearch中,字段数据类型有如下经常使用的类型:sql
- 简单类型
- Text / Keyword - 文本 / 关键字
- Date - 日期
- Integer / Float - 数字 / 浮点
- Boolean - 布尔值
- IPv4 / IPv6 - ip地址
- 复杂类型,包括对象和数组
- 对象
- 数组
- 特殊类型,如地理信息
- geo_point / ...
Dynamic Mapping
Dynamic Mapping 翻译为动态Mapping:数据库
- 在写入文档时,若是索引不存在,会自动建立索引
- 这种机制,使得咱们无需手动定义mappings。Elasticsearch会自动根据文档信息,推算出字段的类型
- 有的时候,Elasticsearch可能会推算不对,如:地理位置信息
- 当类型推算得不对时,可能致使一些功能没法正常运行,如Range查询。
经常使用类型的自动识别规则swift
类型 | 规则 |
---|---|
字符串 | 匹配到日期格式,设置成Date。 字符串为数字时,当成字符串处理,但咱们设置转换为数字。 其余状况,类型就是Text,而且会增长keyword的子字段 |
布尔值 | Boolean |
浮点数 | Float |
整数 | Long |
对象 | Object |
数组 | 由第一个非空数值的类型决定 |
空值 | 忽略 |
下面是具体推断 demoapi
# 写入文档,查看 Mapping PUT mapping_test/_doc/ 1 { "firstName": "Chan", -- Text "lastName": "Jackie", -- Text "loginDate": "2018-07-24T10:29:48.103Z" -- Date } # Dynamic Mapping,推断字段的类型 PUT mapping_test/_doc/ 1 { "uid": "123", -- Text "isVip": false, -- Boolean "isAdmin": "true", -- Text "age": 19, -- Long "heigh": 180 -- Long } # 查看 Dynamic Mapping GET mapping_test/_mapping
可否更改mapping的字段类型
分两种状况:数组
一、新增长的字段app
- dynamic设为true时,新增字段的文档写入时,Mapping同时被更新
- dynamic设为false时,Mapping不会被更新,新增字段的数据没法被索引,可是会出如今_source中
- dynamic设为strict,文档将写入失败
二、已存在的字段,一旦数据被写入,就再也不支持修改字段定义学习
- Lucene自己的限制
- 若是但愿更改字段类型,必须Reindex api,即:重建索引。在数据量多的时候,开销将很是大
# dynamic设置为 false PUT idx1 { "mapping": { "_doc": { "dynamic": "false" } } } # 修改成 dynamic为 false PUT idx1/_mapping { "dynamic": false } # 查看索引 GET idx1/_mapping
dynamic属性和索引字段可变性的规则,咱们能够总结以下:
\ | true | false | strict |
---|---|---|---|
文档可索引 | yes | yes | no |
字段可索引 | yes | no | no |
Mapping被更新 | yes | no | no |
显式Mapping及常见参数
在本文的上一段落,咱们的Mapping都是自动生成的。自动生成机制虽然方便,可是也可能致使一些问题。好比:生成的字段类型不正确,字段的附加属性不知足咱们的需求,等等。这时,咱们能够经过显式Mapping的方式来解决。
那么,咱们如何进行显式Mapping的设置呢?
- 参考官网api,纯手写
- 为减小工做量,减小出错几率,可以下进行:
- 建立一个临时index,写入一些样本数据
- 经过访问Mapping API获取该临时文件的动态Mapping定义
- 修改后,再使用此配置建立本身的索引
- 删除临时索引
咱们推荐使用第二种方式,效率高,且不容易出错。
控制当前字段是否被索引———index
index,可用于设置字段是否被索引,默认为true,false即为不可搜索。在下述例子中,mobile字段将不能被搜索到。
# index属性控制 字段是否能够被索引 PUT user_test { "mappings": { "properties": { "firstName":{ "type": "text" }, "lastName":{ "type": "text" }, "mobile" :{ "type": "text", "index": false } } } }
常见参数 - index_options
记录索引级别。Text类型默认为positions,其余类型默认为docs。咱们须要记住一条准则。
记录的内容越多,占用的存储空间就越大。
索引级别有如下几种,更细节的内容可参考官网
- docs
- freqs
- positions
- offsets
null_value设置
须要对Null值实现搜索时使用。只有keyword类型才支持设定null_value
# 设定Null_value DELETE users PUT users { "mappings" : { "properties" : { "firstName" : { "type" : "text" }, "lastName" : { "type" : "text" }, "mobile" : { "type" : "keyword", "null_value": "NULL" } } } } PUT users/_doc/ 1 { "firstName": "Zhang", "lastName": "Fubing", "mobile": null } PUT users/_doc/ 2 { "firstName": "Zhang", "lastName": "Fubing2" } # 查看结果,有且仅有_id为2的记录 GET users/_search { "query": { "match": { "mobile": "NULL" } } }
copy_to
这个属性用于将当前字段拷贝到指定字段。
_all
在7.x版本已经被copy_to
所代替- 可用于知足特定场景
copy_to
将字段数值拷贝到目标字段,实现相似_all
的做用copy_to
的目标字段不出如今_source中
DELETE user_test #设置 Copy to PUT user_test { "mappings": { "properties": { "firstName":{ "type": "text", "copy_to": "fullName" }, "lastName":{ "type": "text", "copy_to": "fullName" } } } } PUT user_test/_doc/ 1 { "firstName": "Ruan", "lastName": "Yiming" } POST user_test/_search?q=fullName:(Ruan Yiming)
数组类型
Elasticsearch不提供专门的数组类型。但任何字段,均可以包含多个相同类型的数值。
# 数组类型 PUT users/_doc/ 1 { "name": "onebird", "interests": "reading" } PUT users/_doc/ 1 { "name": "twobirds", "interests":[ "reading", "music"] } POST users/_search { "query": { "match_all": {} } } # interests字段仍是text类型 GET users/_mapping