1.什么是Mapping
Mapping 类似 mysql 中的 schema 的定义
用于定义索引属性字段的名称、字段的数据类型 (如 text , long , keyword…)、字段的倒排索引相关配置
一个Mapping 属于一个索引的Type、每个文档都属于一个Type
es7.0开始, 在Mapping中不需要指定 Type信息, 因为7.0之后只有_doc Type
2.自动创建Mapping
当我们去创建一个 索引的时候 未指定 mapping , es会默认帮这个索引创建一个 mapping
例:创建一个索引testmapping
创建一个空索引:
PUT testmapping
创建成功:
{
"acknowledged" : true,
"shards_acknowledged" : true,
"index" : "testmapping"
}
查询该索引mapping信息:
GET testmapping/_mapping
返回结果:
{
"testmapping" : {
"mappings" : { }
}
}
此时可以看到ES为我们创建了一个空mapping的索引,如果我们在创建索引的时候指定字段,ES也会生成我们指定的字段类型,或者默认的类型
创建名为user的索引,并指定字段及字段类型
PUT /user
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word"
},
"language": {
"type": "keyword"
},
"price": {
"type": "double"
},
"publish_time": {
"type": "date",
"format": "yyy-MM-dd"
}
}
}
}
获取user的mapping信息
GET user/_mapping
{
"user" : {
"mappings" : {
"properties" : {
"language" : {
"type" : "keyword"
},
"price" : {
"type" : "double"
},
"publish_time" : {
"type" : "date",
"format" : "yyy-MM-dd"
},
"title" : {
"type" : "text",
"analyzer" : "ik_max_word"
}
}
}
}
}
动态映射(dynamic mapping)
关系型数据库: 先创建表 => 指定字段和字段类型 => 数据写入表
在ES中,索引就相当于表,文档就相当于记录,文档里面的字段就相当于表的字段,字段同样有数据类型。mapping就用来定义文档有哪些字段,这些字段如何存储和索引。
ES与关系型数据库不同之处在于: 其不需要先定义表结构,而可以根据写入文档的内容,来推断字段和数据类型,创建索引结构,这就是dynamic mapping,动态映射的由来。这提供了极大的灵活性。
注:一个索引的字段数量有上限的,超过上限就会报错(默认单个索引创建最大1000个字段)
dynamic参数设置:
按dynamic值,可分为下面三种模式
动态模式(dynamic:true),根据输入文档的内容,自动推断字段和类型,创建mapping
非动态模式(dynamic:false),无法根据输入文档的内容,自动创建mapping,需要手动创建mapping
严格模式(dynamic:strict),同非动态模式,区别在于,非动态模式,输入的文档中如果有字段不在mapping中,依然可以存储和读取,但是该字段不在mapping中,因此也无法根据该字段进行检索;但严格模式,无法存储,会直接报错,严格模式实际上就类似于关系型数据库中的表了。
1.动态模式
直接对一个不存在的索引插入一条数据
POST dynamictrue/_doc
{
"name": "张三",
"age": 15
}
插入成功,获取该索引的mapping信息
GET dynamictrue/_mapping
{
"dynamictrue" : {
"mappings" : {
"properties" : {
"age" : {
"type" : "long"
},
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
在动态模式下,ES会根据插入的数据自动生成对应的字段类型,也可以通过动态模板(dynamic template)来覆盖这个规则,实现自定义推测规则,具体可以参考ES官网
1.1动态模式下索引文档
GET dynamictrue/_search
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "dynamictrue",
"_type" : "_doc",
"_id" : "ulYk54wBAEWV3dbHq4Dj",
"_score" : 1.0,
"_source" : {
"name" : "张三",
"age" : 15
}
}
]
}
}
结论: 动态模式下索引文档是有数据返回的
1.2动态模式下索引字段
-- 查询当前索引下age是15的数据
GET dynamictrue/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"age": {
"value": 15
}
}
}
]
}
}
}
返回值:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "dynamictrue",
"_type" : "_doc",
"_id" : "ulYk54wBAEWV3dbHq4Dj",
"_score" : 1.0,
"_source" : {
"name" : "张三",
"age" : 15
}
}
]
}
}
结论: 动态模式下索引字段也是可以的
1.3动态模式下变更Mapping
新增一个字段
POST dynamictrue/_doc
{
"addr": "地址"
}
成功新增名为addr的字段
GET dynamictrue/_mapping
{
"dynamictrue" : {
"mappings" : {
"properties" : {
"addr" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"age" : {
"type" : "long"
},
"name" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
}
2.非动态模式
新建一个索引(dynamicfalse)并设置dynamic为false
PUT dynamicfalse
{
"settings": {
"index": {
"number_of_shards": "5",
"number_of_replicas": "1"
}
},
"mappings": {
"dynamic": false,
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "long"
}
}
}
}
查询索引(dynamicfalse)的mapping信息
GET dynamicfalse/_mapping
{
"dynamicfalse" : {
"mappings" : {
"dynamic" : "false",
"properties" : {
"age" : {
"type" : "long"
},
"name" : {
"type" : "text"
}
}
}
}
}
此时可以看到返回结果中dynamic已经被设置成false了
此时我们对该索引新增一条数据
POST dynamicfalse/_doc
{
"name": "张三",
"age": 15
}
2.1非动态模式下索引文档
GET dynamicfalse/_search
查询结果:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "dynamicfalse",
"_type" : "_doc",
"_id" : "hFYi54wBAEWV3dbHdYDM",
"_score" : 1.0,
"_source" : {
"name" : "张三",
"age" : 15
}
}
]
}
}
结论: 非动态模式下索引文档是有数据返回的
2.2非动态模式下索引字段
GET dynamicfalse/_search
{
"query": {
"match": {
"age": 15
}
}
}
返回结果:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "dynamicfalse",
"_type" : "_doc",
"_id" : "z1a154wBAEWV3dbHQYzt",
"_score" : 1.0,
"_source" : {
"name" : "张三",
"age" : 15
}
}
]
}
}
结论: 非动态模式下索引字段是可以的,但是只针对查询在mapping中存在的字段生效,如果字段不存在mapping,无法生效,请往下看↓
2.3非动态模式下变更Mapping
在当前索引中插入一个addr字段的数据
POST dynamicfalse/_doc
{
"addr": "地址"
}
插入成功后,查询当前索引mapping信息
GET dynamicfalse/_mapping
{
"dynamicfalse" : {
"mappings" : {
"dynamic" : "false",
"properties" : {
"age" : {
"type" : "long"
},
"name" : {
"type" : "text"
}
}
}
}
}
可以发现非动态模式下新增的字段并没有在mapping中生成
此时查询当前索引中数据
GET dynamicfalse/_search
返回数据如下:
{
"took" : 537,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "dynamicfalse",
"_type" : "_doc",
"_id" : "cVa654wBAEWV3dbHtI3g",
"_score" : 1.0,
"_source" : {
"addr" : "地址"
}
},
{
"_index" : "dynamicfalse",
"_type" : "_doc",
"_id" : "z1a154wBAEWV3dbHQYzt",
"_score" : 1.0,
"_source" : {
"name" : "张三",
"age" : 15
}
}
]
}
}
此时可以发现addr为地址的数据已经成功插入到了当前索引中
此时再根据addr字段索引数据
GET dynamicfalse/_search
{
"query": {
"match": {
"addr": "地址"
}
}
}
返回结果如下:
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 0,
"relation" : "eq"
},
"max_score" : null,
"hits" : [ ]
}
}
结论: 非动态模式下变更mapping是无法在mapping中生成的,新增的数据虽然可以存储,但是无法被新增的字段索引,只能根据文档索引或者已存在mapping中的字段索引所带出
3.严格模式
新建一个索引(dynamicfalse)并设置dynamic为strict
PUT dynamicstrict
{
"settings": {
"index": {
"number_of_shards": "5",
"number_of_replicas": "1"
}
},
"mappings": {
"dynamic": "strict",
"properties": {
"name": {
"type": "text"
},
"age": {
"type": "long"
}
}
}
}
查询当前索引(dynamicstrict)的mapping信息
GET dynamicstrict/_mapping
{
"dynamicstrict" : {
"mappings" : {
"dynamic" : "strict",
"properties" : {
"age" : {
"type" : "long"
},
"name" : {
"type" : "text"
}
}
}
}
}
新增一条数据
POST dynamicstrict/_doc
{
"name": "张三",
"age": 15
}
3.1严格模式下索引文档
GET dynamicstrict/_search
{
"took" : 0,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 1.0,
"hits" : [
{
"_index" : "dynamicstrict",
"_type" : "_doc",
"_id" : "-1bS54wBAEWV3dbH3I99",
"_score" : 1.0,
"_source" : {
"name" : "张三",
"age" : 15
}
}
]
}
}
结论: 严格模式下索引文档是可以的
3.2严格模式下索引字段
GET dynamicstrict/_search
{
"query": {
"match": {
"name": "张三"
}
}
}
返回结果如下:
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 0.5753642,
"hits" : [
{
"_index" : "dynamicstrict",
"_type" : "_doc",
"_id" : "-1bS54wBAEWV3dbH3I99",
"_score" : 0.5753642,
"_source" : {
"name" : "张三",
"age" : 15
}
}
]
}
}
结论:严格模式下索引mapping中存在的字段也是可以的
3.3严格模式下变更Mapping文章来源:https://www.toymoban.com/news/detail-812490.html
POST dynamicstrict/_doc
{
"addr": "地址"
}
返回报错信息如下:
{
"error" : {
"root_cause" : [
{
"type" : "strict_dynamic_mapping_exception",
"reason" : "mapping set to strict, dynamic introduction of [addr] within [_doc] is not allowed"
}
],
"type" : "strict_dynamic_mapping_exception",
"reason" : "mapping set to strict, dynamic introduction of [addr] within [_doc] is not allowed"
},
"status" : 400
}
结论: 严格模式下无法新增字段,此模式可以用于在工作中防止自己的索引字段被人修改文章来源地址https://www.toymoban.com/news/detail-812490.html
到了这里,关于【ElasticSearch-基础篇】Mapping结构的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!