7. elk的mapping
mapping¶
- 类似数据库中的schema
1 定义索引中的字段名称
2 定义字段的数据类型
3 字段,倒排索引的相关配置(analyzed)
-
mapping会把json文档映射成lucene所需的扁平化格式
-
一个mapping属于一个索引的type
1 每个文档都属于一个type
2 一个type有一个mapping定义
3 7.0开始不需要在mapping定义中指定type信息
字段类型¶
1 text/keyword
2 date
3 integer/floating
4 boolean
5 IPV4/IPV6
复杂类型对象和嵌套对象
特殊类型
Dynamic Mapping¶
1 写入文档时候,如果索引不存在,会自动创建索引
2 Dynamic mapping机制,使得我们无需手动定义mappings,elasticsearch会自动更具文档信息,推算出字段的类型
3 当类型设置不对时,会导致一个功能无法使用,如range查询
查看mapping GET movie/_mapping
类型的自动识别¶
实战
#写入文档,查看 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的字段类型??¶
- 新增字段
1 Dynamic设置为true,一旦新增字段的文档写入,mapping会同时 更新
2 Dynamic设置为false,mapping不会更新,但是文档可以被索引,新增的字段无法被索引,但是信息会出现在_source中
3 Dynamic设置为strict,文档写入失败
- 对于已有字段,一旦已经有数据写入,就不在支持修改字段定义
1 如果希望修改字段类型,必须reindex API重新建立索引
PUT movies
{
mappings:{
docs:{
"dynamic":"true"
}
}
#默认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的一些建议¶
1 创建一个临时的index,写入一些样本数据
2 通过访问mapping api或的该临时文件的动态mapping定义
3 修改后用,使用该配置创建你的索引
4 删除临时索引
- 控制当前字段是否被索引
使用参数index ,默认是true,false是表示该字段不能被索引
PUT users
{
"mappings" : {
"properties" : {
"firstName" : {
"type" : "text"
},
"lastName" : {
"type" : "text"
},
"mobile" : {
"type" : "text",
"index": false
}
}
}
}
index options参数可以控制倒排索引记录的内容
1 docs 记录doc id
2 freqs 记录doc id 和term frequencies
3 positions 记录doc id /term frequencies/term position
4 offsets 记录doc id /character offsets/term frequencies/term position
其中Text类型默认是positions其他默认docs
记录内容越多,暂用存储空间越大
PUT users
{
"mappings" : {
"properties" : {
"firstName" : {
"type" : "text"
},
"lastName" : {
"type" : "text",
"index_options":"offsets"
},
"mobile" : {
"type" : "text",
"index": false
}
}
}
}
null_value¶
需要对null值进行搜索
只有keyword类型支持null_value
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
}
GET users/_search
{
"query": {
"match": {
"mobile":"NULL"
}
}
}
copy_to将字段的数值拷贝到目标字段中,实现类似all的作用
copy_to的字段不出现在_source中
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)
数组类型¶
没有专门的数组类型,跟其他写法一样
#数组类型
PUT users/_doc/1
{
"name":"onebird",
"interests":"reading"
}
PUT users/_doc/1
{
"name":"twobirds",
"interests":["reading","music"]
}
POST users/_search
{
"query": {
"match_all": {}
}
}
exact value OR full text¶
1 exact value 包括数字/日期/具体的一个字符串,是elasticsearch中的keyword,exact value是不需要分词的
2 full text非结构化的文本数据,是elastcsearch中的text
自定义分词器¶
自定义分词通过组合不同的组件实现
- character Filter

POST _analyze
{
"tokenizer":"keyword",
"char_filter":["html_strip"],
"text": "<b>hello world</b>"
}
#使用char filter进行替换
POST _analyze
{
"tokenizer": "standard",
"char_filter": [
{
"type" : "mapping",
"mappings" : [ "- => _"]
}
],
"text": "123-456, I-test! test-990 650-555-1234"
}

- Token filter

GET _analyze
{
"tokenizer": "whitespace",
"filter": ["stop","snowball"],
"text": ["The gilrs in China are playing this game!"]
}
//remove 加入lowercase后,The被当成 stopword删除
GET _analyze
{
"tokenizer": "whitespace",
"filter": ["lowercase","stop","snowball"],
"text": ["The gilrs in China are playing this game!"]
}