赞
踩
Mapping 类似 mysql 中的 schema 的定义
用于定义索引属性字段的名称、字段的数据类型 (如 text , long , keyword…)、字段的倒排索引相关配置
一个Mapping 属于一个索引的Type、每个文档都属于一个Type
es7.0开始, 在Mapping中不需要指定 Type信息, 因为7.0之后只有_doc Type
当我们去创建一个 索引的时候 未指定 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" } } } } }
关系型数据库: 先创建表 => 指定字段和字段类型 => 数据写入表
在ES中,索引就相当于表,文档就相当于记录,文档里面的字段就相当于表的字段,字段同样有数据类型。mapping就用来定义文档有哪些字段,这些字段如何存储和索引。
ES与关系型数据库不同之处在于: 其不需要先定义表结构,而可以根据写入文档的内容,来推断字段和数据类型,创建索引结构,这就是dynamic mapping,动态映射的由来。这提供了极大的灵活性。
注:一个索引的字段数量有上限的,超过上限就会报错(默认单个索引创建最大1000个字段)
dynamic参数设置:
按dynamic值,可分为下面三种模式
动态模式(dynamic:true),根据输入文档的内容,自动推断字段和类型,创建mapping
非动态模式(dynamic:false),无法根据输入文档的内容,自动创建mapping,需要手动创建mapping
严格模式(dynamic:strict),同非动态模式,区别在于,非动态模式,输入的文档中如果有字段不在mapping中,依然可以存储和读取,但是该字段不在mapping中,因此也无法根据该字段进行检索;但严格模式,无法存储,会直接报错,严格模式实际上就类似于关系型数据库中的表了。
直接对一个不存在的索引插入一条数据
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 } } } } } } }
新建一个索引(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中的字段索引所带出
新建一个索引(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
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 }
结论: 严格模式下无法新增字段,此模式可以用于在工作中防止自己的索引字段被人修改
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。