Elasticsearch
DynamicMapping和常见字段类型
Mapping中的字段一旦设定后,禁止直接修改。因为倒排索引生成后不允许直接修改。需要重新建立新的索引,做reindex操作。
类似数据库中的表结构定义,主要作用
- 定义所以下的字段名字
- 定义字段的类型
- 定义倒排索引相关的配置(是否被索引?采用的Analyzer)
对新增字段的处理
true
false
strict
在object下,支持做dynamic的属性的定义
什么是Mapping
-
Mapping 类似数据库中的schema的定义,作用如下
- 定义索引中的字段的名 称
- 定义字段的数据类型,例如字符串,数字,布尔…
- 字段, 倒排索引的相关配置,(Analyzed or Not Analyzed,Analyzer)
-
Mapping会把JSON文档映射成Lucene所需要的扁平格式
-
一个Mapping属于一个索引的Type
- 每个文档都属于一 个Type
- 一个Type有一一个Mapping定义
- 7.0 开始,不需要在Mapping定义中指定type信息
字段的数据类型
-
简单类型
- Text / Keyword
- Date
- Integer / Floating
- Boolean
- IPv4 & IPv6
-
复杂类型- 对象和嵌套对象
- 对象类型/嵌套类型
-
特殊类型
- geo_ point & geo shape / percolator
什么是Dynamic Mapping
-
在写入文档时候,如果索引不存在,会自动创建索引
-
Dynamic Mapping的机制,使得我们无需手动定义Mappings。Elasticsearch会自动根据文档信息,推算出字段的类型
-
但是有时候会推算的不对,例如地理位置信息
-
当类型如果设置不对时,会导致一些功能无法正常运行,例如Range查询
类型的自动识别
能否更改Mapping的字段类型
-
两种情况
-
新增加字段
- Dynamic设为true时,-旦有新增字段的文档写入,Mapping 也同时被更新
- Dynamic设为false, Mapping 不会被更新,新增字段的数据无法被索引,但是信息会出现在. _source中
- Dynamic设置成Strict,文档写入失败
-
对已有字段,一旦已经有数据写入,就不再支持修改字段定义
- Lucene实现的倒排索引,一旦生成后,就不允许修改
-
如果希望改变字段类型,必须Reindex API,重建索引
-
-
原因
+ 如果修改了字段的数据类型,会导致已被索引的属于无法被搜索
+ 但是如果是增加新的字段,就不会有这样的影响
控制Dynamic Mappings
- 当 dynamic被设置成false时候,存在新增字段的数据写入,该数据可以被索引,
但是新增字段被丢弃 - 当设置 成Strict模式时候,数据写入直接出错
API
#写入文档,查看 Mapping
PUT mapping_test/_doc/1
{
"firstName":"Chan",
"lastName": "Jackie",
"loginDate":"2018-07-24T10:29:48.103Z"
}
#查看 Mapping文件
GET mapping_test/_mapping
#Delete index
DELETE mapping_test
#dynamic mapping,推断字段的类型
PUT mapping_test/_doc/1
{
"uid" : "123",
"isVip" : false,
"isAdmin": "true",
"age":19,
"heigh":180
}
#查看 Dynamic
GET mapping_test/_mapping
#默认Mapping支持dynamic,写入的文档中加入新的字段
PUT dynamic_mapping_test/_doc/1
{
"newField":"someValue"
}
#该字段可以被搜索,数据也在_source中出现
POST dynamic_mapping_test/_search
{
"query":{
"match":{
"newField":"someValue"
}
}
}
#修改为dynamic false
PUT dynamic_mapping_test/_mapping
{
"dynamic": false
}
#新增 anotherField
PUT dynamic_mapping_test/_doc/10
{
"anotherField":"someValue"
}
#该字段不可以被搜索,因为dynamic已经被设置为false
POST dynamic_mapping_test/_search
{
"query":{
"match":{
"anotherField":"someValue"
}
}
}
get dynamic_mapping_test/_doc/10
#修改为strict
PUT dynamic_mapping_test/_mapping
{
"dynamic": "strict"
}
#写入数据出错,HTTP Code 400
PUT dynamic_mapping_test/_doc/12
{
"lastField":"value"
}
DELETE dynamic_mapping_test
显式Mapping设置与常见参数介绍
如何显示定义-个Mapping
自定义Mapping的一些建议
- 可以参考API手册,纯手写
- 为 了减少输入的工作量,减少出错概率,可以依照以下步骤
- 创建一个临时的index,写入-些样本数据
- 通过访问 Mapping API获得该临时文件的动态Mapping定义
- 修改后用,使用该配置创建你的索引
- 删除临时索引
控制当前字段是否被索引
- Index -控制当前字段是否被索引。默认为true。如果设置成false, 该字段不可被搜索
Index Options
null value
copy_to 设置
数组类型
- Elasticsearch中不 提供专门的数组类型。但是任何字段,都可以包含多个相同类类型的数值
API demo
#设置 index 为 false
DELETE users
PUT users
{
"mappings" : {
"properties" : {
"firstName" : {
"type" : "text"
},
"lastName" : {
"type" : "text"
},
"mobile" : {
"type" : "text",
"index": false
}
}
}
}
PUT users/_doc/1
{
"firstName":"Ruan",
"lastName": "Yiming",
"mobile": "12345678"
}
POST /users/_search
{
"query": {
"match": {
"mobile":"12345678"
}
}
}
#设定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":"Ruan",
"lastName": "Yiming",
"mobile": null
}
PUT users/_doc/2
{
"firstName":"Ruan2",
"lastName": "Yiming2"
}
GET users/_search
{
"query": {
"match": {
"mobile":"NULL"
}
}
}
#设置 Copy to
DELETE users
PUT users
{
"mappings": {
"properties": {
"firstName":{
"type": "text",
"copy_to": "fullName"
},
"lastName":{
"type": "text",
"copy_to": "fullName"
}
}
}
}
PUT users/_doc/1
{
"firstName":"Ruan",
"lastName": "Yiming"
}
GET users/_search?q=fullName:(Ruan Yiming)
POST users/_search
{
"query": {
"match": {
"fullName":{
"query": "Ruan Yiming",
"operator": "and"
}
}
}
}
#数组类型
PUT users/_doc/1
{
"name":"onebird",
"interests":"reading"
}
PUT users/_doc/1
{
"name":"twobirds",
"interests":["reading","music"]
}
POST users/_search
{
"query": {
"match_all": {}
}
}
GET users/_mapping