1、 新增Document
在索引中增长文档。在index中增长document。
ES有自动识别机制。若是增长的document对应的index不存在。自动建立,若是index存在,type不存在自动建立。若是index和type都存在,则使用现有的。java
1.1 PUT语法
此操做为手工指定id的Document新增方式。
PUT /index_name/type_name/id{field_name:field_value}
如:node
PUT /test_index/my_type/1 { "name":"test_doc_01", "remark":"first test elastic search", "order_no":1 } PUT /test_index/my_type/2 { "name":"test_doc_02", "remark":"second test elastic search", "order_no":2 } PUT /test_index/my_type/3 { "name":"test_doc_03", "remark":"third test elastic search", "order_no":3 }
结果:算法
{ "_index": "test_index", 新增的document在什么index中, "_type": "my_type", 新增的document在index中的哪个type中。 "_id": "1", 指定的id是多少 "_version": 1, document的版本是多少,版本从1开始递增,每次写操做都会+1 "result": "created", 本次操做的结果,created建立,updated修改,deleted删除 "_shards": { 分片信息 "total": 2, 分片数量只提示primary shard "successful": 1, 数据document必定只存放在index中的某一个primary shard中 "failed": 0 }, "_seq_no": 0, 执行的序列号 "_primary_term": 1 词条比对。 }
1.2 POST语法
此操做为ES自动生成id的新增Document方式。
语法:POST /index_name/type_name{fieldname:fieldvalue}
如:json
POST /test_index/my_type { "name":"test_doc_04", "remark":"forth test elastic search", "order_no":4 }
注意:在ES中,一个index中的全部type类型的Document是存储在一块儿的,若是index中的不一样的type之间的field差异太大,也会影响到磁盘的存储结构和存储空间的占用。如:test_index中有test_type1和test_type2两个不一样的类型,type1中的document结构为:{"_id":"1","f1":"v1","f2":"v2"},type2中的document结构为:{"_id":"2","f3":"v3","f4":"v4"},那么ES在存储的时候,统一的存储方式是{"_id":"1","f1":"v1","f2":"v2","f3":"","f4":""}, {"_id":"2","f1":"","f2":"","f3":"v3","f4","v4"}、建议,每一个index中存储的document结构不要有太大的差异。尽可能控制在总计字段数据的10%之内。api
2、 查询Document
2.1 GET查询
GET /index_name/type_name/id
如:并发
GET /test_index/my_type/1
结果:负载均衡
{ "_index": "test_index", "_type": "my_type", "_id": "1", "_version": 1, "found": true, "_source": { 找到的document数据内容。 "name": "test_doc_01", "remark": "first test elastic search", "order_no":1 } }
2.2 GET _mget批量查询
批量查询能够提升查询效率。推荐使用(相对于单数据查询来讲)。
语法:jvm
GET /_mget { "docs" : [ { "_index" : "value", "_type" : "value", "_id" : "value" },{}, {} ] } GET /index_name/_mget { "docs" : [ { "_type" : "value", "_id" : "value" }, {}, {} ] } GET /index_name/type_name/_mget { "docs" : [ { "_id" : "value1" }, { "_id" : "value2" } ] }
3、 修改Document
3.1 替换Document(全量替换)
和新增的PUT语法是一致。
PUT /index_name/type_name/id{field_name:new_field_value}
要求新数据的字段信息和原数据的字段信息一致。也就是必须包括Document中的全部field才行。本操做至关于覆盖操做。全量替换的过程当中,ES不会真的修改Document中的数据,而是标记ES中原有的Document为deleted状态,再建立一个新的Document来存储数据,当ES中的数据量过大时,ES后台回收deleted状态的Document(现阶段理解,后续课程中会详细说明)。
如:性能
PUT /test_index/my_type/1 { "name":"new_test_doc_01", "remark":"first test elastic search", "order_no":1 }
结果:spa
{ "_index": "test_index", "_type": "my_type", "_id": "1", "_version": 2, "result": "updated", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 1, "_primary_term": 1 }
3.2 PUT语法强制新增
若是使用PUT语法对同一个Document执行屡次操做。是一种全量替换操做。若是须要ES辅助检查PUT的Document是否已存在,可使用强制新增语法。使用强制新增语法时,若是Document的id在ES中已存在,则会报错。(version conflict, document already exists)
语法:
PUT /index_name/type_name/id/_create
或
PUT /index_name/type_name/id?op_type=create。
如:
PUT /test_index/my_type/1/_create { "name":"new_test_doc_01", "remark":"first test elastic search", "order_no":1 }
3.3 更新Document(partial update)
POST /index_name/type_name/id{field_name:field_value_for_update}
只更新某Document中的部分字段。这种更新方式也是标记原有数据为deleted状态,建立一个新的Document数据,将新的字段和未更新的原有字段组成这个新的Document,并建立。对比全量替换而言,只是操做上的方便,在底层执行上几乎没有区别。
如:
POST /test_index/my_type/1/_update { "doc":{ "name":" test_doc_01_for_update" } }
结果:
{ "_index": "test_index", "_type": "my_type", "_id": "1", "_version": 5, "result": "updated", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 2, "_primary_term": 1 }
4、 删除Document
ES中执行删除操做时,ES先标记Document为deleted状态,而不是直接物理删除。当ES存储空间不足或工做空闲时,才会执行物理删除操做。标记为deleted状态的数据不会被查询搜索到。
ES中删除index,也是标记。后续才会执行物理删除。全部的标记动做都是为了NRT实现(近实时)。
DELETE /index_name/type_name/id
如:
DELETE /test_index/my_type/1
结果:
{ "_index": "test_index", "_type": "my_type", "_id": "1", "_version": 6, "result": "deleted", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 5, "_primary_term": 1 }
5、 bulk批量增删改
使用bulk语法执行批量增删改。语法格式以下:
POST /_bulk
{ "action_type" : { "metadata_name" : "metadata_value" } }
{ document datas | action datas }
语法中的action_type可选值为:
create : 强制建立,至关于PUT /index_name/type_name/id/_create
index: 普通的PUT操做,至关于建立Document或全量替换
update: 更新操做(partial update),至关于 POST /index_name/type_name/id/_update
delete: 删除操做
案例以下:下述案例中将全部的操做语法分离了。能够一次性执行增删改的全部功能。最后的语法是批量操做语法。
POST /_bulk { "create" : { "_index" : "test_index" , "_type" : "my_type", "_id" : "1" } } { "field_name" : "field value" } POST /_bulk { "index" : { "_index" : "test_index", "_type" : "my_type" , "_id" : "2" } } { "field_name" : "field value 2" } POST /bulk { "update" : { "_index" : "test_index", "_type" : "my_type" , "_id" : 2", "_retry_on_conflict" : 3 } } { "doc" : { "field_name" : "partial update field value" } } POST /_bulk { "delete" : { "_index" : "test_index", "_type" : "my_type", "_id" : "2" } } POST /_bulk { "create" : { "_index" : "test_index" , "_type" : "my_type", "_id" : "10" } } { "field_name" : "field value" } { "index" : { "_index" : "test_index", "_type" : "my_type" , "_id" : "20" } } { "field_name" : "field value 2" } { "update" : { "_index" : "test_index", "_type" : "my_type" , "_id" : 20, "_retry_on_conflict" : 3 } } { "doc" : { "field_name" : "partial update field value" } } { "delete" : { "_index" : "test_index", "_type" : "my_type", "_id" : "2" } }
注意:bulk语法中要求一个完整的json串不能有换行。不一样的json串必须使用换行分隔。多个操做中,若是有错误状况,不会影响到其余的操做,只会在批量操做返回结果中标记失败。bulk语法批量操做时,bulk request会一次性加载到内存中,若是请求数据量太大,性能反而降低(内存压力太高),须要反复尝试一个最佳的bulk request size。通常从1000~5000条数据开始尝试,逐渐增长。若是查看bulk request size的话,通常是5~15MB之间为好。
解释:bulk语法要求json格式是为了对内存的方便管理,和尽量下降内存的压力。若是json格式没有特殊的限制,ES在解释bulk请求时,须要对任意格式的json进行解释处理,须要对bulk请求数据作json对象会json array对象的转化,那么内存的占用量至少翻倍,当请求量过大的时候,对内存的压力会直线上升,且须要jvm gc进程对垃圾数据作频繁回收,影响ES效率。
生成环境中,bulk api经常使用。都是使用java代码实现循环操做。通常一次bulk请求,执行一种操做。如:批量新增10000条数据等。
6、 Document routing 机制
ES对Document的管理有一个路由算法,这种算法决定了Document存放在哪个primary shard中。算法为:primary shard = hash(routing) % number_of_primary_shards。其中的routing默认为Document中的元数据_id,也能够手工指定routing的值,指定方式为:PUT /index_name/type_name/id?routing=xxx。手工指定routing在海量数据中很是有用,经过手工指定的routing,ES会将相关联的Document存储在同一个shard中,方便后期进行应用级别的负载均衡并能够提升数据检索的效率。如:存电商中的商品,使用商品类型的编号做为routing,ES会把同一个类型的商品document数据,存在同一个shard中。查询的时候,同一个类型的商品,在一个shard上查询,效率最高。
若是是写操做。计算routing结果后,决定本次写操做定位到哪个primary shard分片上,primary shard 分片写成功后,自动同步到对应replica shard上。若是是读操做,计算routing结果后,决定本次读操做定位到哪个primary shard 或其对应的replica shard上。实现读负载均衡,replica shard数量越多,并发读能力越强。
PUT /test_index/my_type/10?routing=type_id{}
7、 Document增删改原理简图
解释:
1 : 客户端发起请求,执行增删改操做。全部的增删改操做都由primary shard直接处理,replica shard只被动的备份数据。此操做请求到节点2(请求发送到的节点随机),这个节点称为协调节点(coordinate node)。
2 : 协调节点经过路由算法,计算出本次操做的Document所在的shard。假设本次操做的Document所在shard为 primary shard 0。协调节点计算后,会将操做请求转发到节点1。
3 : 节点1中的primary shard 0在处理请求后,会将数据的变化同步到对应的replica shard 0中,也就是发送一个同步数据的请求到节点3中。
4 : replica shard 0在同步数据后,会响应通知请求这同步成功,也就是响应给primary shard 0(节点1)。
5 : primary shard 0(节点1)接收到replica shard 0的同步成功响应后,会响应请求者,本次操做完成。也就是响应给协调节点(节点2)。
6 : 协调节点返回响应给客户端,通知操做结果。
8、 Document查询简图
解释:1 : 客户端发起请求,执行查询操做。查询操做都由primary shard和replica shard共同处理。此操做请求到节点2(请求发送到的节点随机),这个节点称为协调节点(coordinate node)。2 : 协调节点经过路由算法,计算出本次查询的Document所在的shard。假设本次查询的Document所在shard为 shard 0。协调节点计算后,会将操做请求转发到节点1或节点3。分配请求到节点1仍是节点3经过随机算法计算,ES会保证当请求量足够大的时候,primary shard和replica shard处理的查询请求数是均等的(是不绝对一致)。3 : 节点1或节点3中的primary shard 0或replica shard 0在处理请求后,会将查询结果返回给协调节点(节点2)。4 : 协调节点获得查询结果后,再将查询结果返回给客户端。