一、创建索引index
创建名为newindex的索引(索引名必须为小写): 提交请求newindex PUT,创建成功出现下面结果:
1{ 2 "acknowledged": true 3}
查看新建的索引:newindex GET,结果如下:
1{ 2 "newindex": { 3 "aliases": { }, 4 "mappings": { }, 5 "settings": { 6 "index": { 7 "creation_date": "1491980889980", 8 "uuid": "DvFfvO0JQ46Bbb0u64rgsw", 9 "number_of_replicas": "1", 10 "number_of_shards": "5", 11 "version": { 12 "created": "2040499" 13 } 14 } 15 }, 16 "warmers": { } 17 } 18}
索引的两个重要配置: number_of_replicas 副本数量(默认1) number_of_shards 分片数量(默认5) 创建索引时自定义副本和分片数量:
newindex1 PUT
1{ 2 "settings": { 3 "index": { 4 "number_of_replicas": "3", 5 "number_of_shards": "3" 6 } 7 } 8}
二、创建类型type
在索引newindex中创建名为newtype的类型:
newindex/newtype/_mapping PUT
1{ 2 "newtype": {} 3}
再查看索引newindex,结果如下:
1{ 2 "newindex": { 3 "aliases": { }, 4 "mappings": { 5 "newtype": { } 6 }, 7 "settings": { 8 "index": { 9 "creation_date": "1491980889980", 10 "uuid": "DvFfvO0JQ46Bbb0u64rgsw", 11 "number_of_replicas": "1", 12 "number_of_shards": "5", 13 "version": { 14 "created": "2040499" 15 } 16 } 17 }, 18 "warmers": { } 19 } 20}
发现"mappings"(映射)中多了newtype。
每个类型(type)拥有自己的映射(mapping)或者模式定义(schema definition),一个映射定义了字段,每个字段的数据类型,以及字段被Elasticsearch处理的方式。
新增一个定义映射的类型newtype1:
newindex/newtype1/_mapping PUT
1{ 2 "newtype1": { 3 "properties": { 4 "id": { 5 "type": "long" 6 }, 7 "name": { 8 "type": "string", 9 "index": "not_analyzed" 10 }, 11 "birth": { 12 "type": "date" 13 } 14 } 15 } 16}
查看新创建的newtype1的映射:
newindex/_mapping/newtype1 GET
1{ 2 "newindex": { 3 "mappings": { 4 "newtype1": { 5 "properties": { 6 "birth": { 7 "type": "date", 8 "format": "strict_date_optional_time||epoch_millis" 9 }, 10 "id": { 11 "type": "long" 12 }, 13 "name": { 14 "type": "string", 15 "index": "not_analyzed" 16 } 17 } 18 } 19 } 20 } 21}
三、索引文档
向es中添加一个文档:
newindex/newtype1/1 PUT
1{ 2 "id": 1, 3 "name": "张三", 4 "birth": "2017-01-02" 5}
返回结果如下,添加成功:
1{ 2 "_index": "newindex", 3 "_type": "newtype1", 4 "_id": "1", 5 "_version": 1, 6 "_shards": { 7 "total": 2, 8 "successful": 2, 9 "failed": 0 10 }, 11 "created": true 12}
查看文档:
newindex/newtype1/1 GET
1{ 2 "_index": "newindex", 3 "_type": "newtype1", 4 "_id": "1", 5 "_version": 1, 6 "found": true, 7 "_source": { 8 "id": 1, 9 "name": "张三", 10 "birth": "2017-01-02" 11 } 12}
创建索引、类型,添加文档可以通过一条指令完成:
1myindex/mytype/1 PUT 2{ 3"id": 1, 4"name": "张三", 5"birth": "2017-01-02" 6}
Elasticsearch检测索引、类型不存在时会自动创建,自动创建索引由配置项action.auto_create_index控制,默认开启为true
四、动态映射
如果上面执行操作前,ES中没有myindex这个索引,那么默认会直接创建这个索引;并且type字段也会自动创建。也就是说,ES并不需要像传统的数据库事先定义表的结构。每个索引中的类型都有一个mapping映射,这个映射是动态生成的,因此当增加新的字段时,会自动增加mapping的设置。
通过在配置文件中设置
action.auto_create_index为false,可以关闭自动创建index这个功能。 自动创建索引功能,也可以设置黑名单或者白名单,比如: 设置action.auto_create_index为+aaa*,-bbb*,'+'号意味着允许创建aaa开头的索引,'-'号意味着不允许创建bbb开头的索引。
通过设置dynamic控制动态映射,可选值:
true:自动添加字段(默认)false:忽略字段strict:当遇到未知字段时抛出异常
向索引myindex中添加类型strict_type:
myindex/strict_type/_mapping PUT
1{ 2 "strict_type": { 3 "dynamic": "strict", 4 "properties": { 5 "title": { 6 "type": "string" 7 }, 8 "stash": { 9 "type": "object", 10 "dynamic": true 11 } 12 } 13 } 14}
将 strict_type 的动态映射设置为了strict,意味着如果向 myindex/strict_type 中添加文档时,如果文档中含有除 title 和 stash 的其他字段时,会抛出异常。测试一下:
myindex/strict_type/1 PUT
1{ 2 "title": "加一个新字段content", 3 "content": "未知字段会抛出异常" 4}
结果如下:
1{ 2 "error": { 3 "root_cause": [ 4 { 5 "type": "strict_dynamic_mapping_exception", 6 "reason": "mapping set to strict, dynamic introduction of [content] within [strict_type] is not allowed" 7 } 8 ], 9 "type": "strict_dynamic_mapping_exception", 10 "reason": "mapping set to strict, dynamic introduction of [content] within [strict_type] is not allowed" 11 }, 12 "status": 400 13}
但是我们在字段 stash 中将dynamic设置为了true,意味着在 stash 对象内可以新增字段,测试一下:
myindex/strict_type/2 PUT
1{ 2 "title": "在stash中加一个新字段content", 3 "stash": { 4 "content": "这下可以加进来了" 5 } 6}
结果添加成功:
1{ 2 "_index": "myindex", 3 "_type": "strict_type", 4 "_id": "2", 5 "_version": 1, 6 "_shards": { 7 "total": 2, 8 "successful": 2, 9 "failed": 0 10 }, 11 "created": true 12}
五、自定义动态映射
使用dynamic_templates,可以完全控制新字段的映射,可以通过设置字段名或数据类型等应用一个完全不同的映射。
向索引 myindex 中添加一个自定义动态映射的类型 my_dynamic_type :
myindex/my_dynamic_type/_mapping PUT
1{ 2 "my_dynamic_type": { 3 "dynamic_templates": [ 4 { 5 "ord": { 6 "match": "*_ord", 7 "match_mapping_type": "string", 8 "mapping": { 9 "type": "string", 10 "index": "not_analyzed" 11 } 12 } 13 }, 14 { 15 "date": { 16 "match": "date_*", 17 "match_mapping_type": "string", 18 "mapping": { 19 "type": "date", 20 "ignore_malformed": true 21 } 22 } 23 } 24 ] 25 } 26}
my_dynamic_type 的映射使用了动态模板,在动态模板dynamic_templates中:
-
定义了一个名为
ord的模板,这个模板匹配所有以_ord结尾("match": "*_ord")字符串类型("match_mapping_type": "string")的字段,将此类字段类型映射为字符串并索引的时候不做解析("mapping": {"type": "string","index": "not_analyzed"}) -
定义了一个名为
date的模板,这个模板匹配所有以date_开头("match": "date_*")字符串类型("match_mapping_type": "string")的字段,将此类字段类型映射为日期类型,并且忽略不能格式化为日期的值("mapping": {"type": "date","ignore_malformed": true})
看下效果:
myindex/my_dynamic_type/1 PUT
1{ 2 "id": 1, 3 "name": "张三", 4 "date_birth": "20170923", 5 "name_ord": "张三" 6}
插入文档后查看 my_dynamic_type 的映射:
myindex/_mappping/my_dynamic_type GET
1{ 2 "myindex": { 3 "mappings": { 4 "my_dynamic_type": { 5 "dynamic_templates": [ { "ord": { "mapping": { "type": "string","index": "not_analyzed"},"match": "*_ord","match_mapping_type": "string"}},{ "date": { "mapping": { "type": "date","ignore_malformed": true},"match": "date_*","match_mapping_type": "string"}}], 6 "properties": { 7 "date_birth": { 8 "type": "date", 9 "ignore_malformed": true, 10 "format": "strict_date_optional_time||epoch_millis" 11 }, 12 "id": { 13 "type": "long" 14 }, 15 "name": { 16 "type": "string" 17 }, 18 "name_ord": { 19 "type": "string", 20 "index": "not_analyzed" 21 } 22 } 23 } 24 } 25 } 26}
可以看到properties中已经将name_ord字段映射为字符串类型,并不做解析;date_birth也映射为了日期类型,再插入一个文档:
myindex/my_dynamic_type/2 PUT
1{ 2 "id": 2, 3 "name": "李四", 4 "date_birth": "未知", 5 "name_ord": "李四" 6}
插入成功,date_birth字段也可以接受不能被格式化为日期的值。
关于动态映射更多配置语法请参考官方文档:
https://www.elastic.co/guide/en/elasticsearch/reference/2.4/dynamic-templates.html
https://www.elastic.co/guide/en/elasticsearch/reference/2.4/mapping.html