put /index/type/id
4.1.2 自动天生
语法
POST /index/type
自动天生的ID,长度是20个字符的GUID,分布式全局唯一。
在我们操作mysql时,想必大部分的公司都是禁止利用 select 的,而哀求用到什么列就查询什么列。

而我们上面利用ES的办法,就相称于在写 select ,这是不推举的,我们在实际利用的时候,可以只查询指定的字段。
语法
GET /index/type/id?_source_includes=字段名,多个字段逗号隔开
article/_doc/1?_source_includes=title,content
4.3 逼迫创建
在上面的学习中,我们创造,更换文档和创建文档的API是一样的,这就意味着,我们在创建文档的过程中,可能这个文档实在已经存在了,但是我们不知道,通过创建的API直接把该文档进行了更换,这不是我们想要的结果,因此须要利用逼迫创建。
逼迫创建限定这个API只能是创建文档,如果指定ID的文档已经存在了,就抛出非常。
语法
PUT /index/type/id/_create
4.4 lazy delete
ES在更换文档、修正文档的时候,实质上并不是直接更换,而是先将旧文档标记为deleted,然后再创建新的文档。此时旧的文档实际上还是存在于索引库里的,并不会立即删除,集群会找个得当的机遇,一并删除所有标记deleted的文档
同样,删除的API也只是标记了deleted,并不是立即删除。
如果删除一条数据立马删除的话,所有分片和副本都要立马删除,对es集群压力太大。
4.5 手动设置版本号我们的数据库中可能已经掩护了版本号,现在须要同步这些数据,同步的时候须要手动设置版本号
可以通过利用 external version 掌握,设置的时候版本号必须大于当前文档的版本号
语法:
PUT /index/type/id?version=要修正的版本号&version_type=external
两个客户端同时修正,只会有一个修正成功。
4.6 批量操作4.6.1 批量查询当我们要根据id查询的时候,如果一条一条查,性能损耗和网络开销大,可以利用批量查询
语法
GET /_mget
_mget是全查询,操作起来并不是那么方便,并且随意马虎报出 request body or source parameter is required 非常,因此利用率较少
4.6.2 批量增编削_bulk 操作将文档的增编削查一系列操作,通过以此要求全部做完,减少网络传输次数
POST /_bulk
把稳,bulk操作的形式是多个json,每个json写完必须换行,而在json内则不可以换行。多个json之间操作互不影响,纵然报错了,其他行也可以正常实行
{"delete": {"_index": "article", "_id": 6}}{"create": {"_index": "article", "_id": 7}}{"title": "我是批量操作中创建的数据,ID是7 "}{"update": {"_index": "article", "_id": 5}}{"doc": {"content": "我在批量操作中进行了修正,但是PHP依然是最好的措辞"}}
总结:
delete:删除一个文档,只要1个json串就可以了create:相称于逼迫创建 PUT /index/type/id/_createindex:普通的put操作,可以是创建文档,也可以是全量更换文档update:实行的是局部更新partial update操作利用json格式发送数据(postman中报错不要紧),末了一行也须要换行{ "took": 6, "errors": true, "items": [ { "delete": { "_index": "article", "_type": "_doc", "_id": "6", "_version": 5, "result": "not_found", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "_seq_no": 31, "_primary_term": 1, "status": 404 } }, { "create": { "_index": "article", "_type": "_doc", "_id": "7", "status": 409, "error": { "type": "version_conflict_engine_exception", "reason": "[7]: version conflict, document already exists (current version [1])", "index_uuid": "uHYrNKR2S1Gf6dsFONzwVg", "shard": "0", "index": "article" } } }, { "update": { "_index": "article", "_type": "_doc", "_id": "5", "_version": 10, "result": "noop", "_shards": { "total": 2, "successful": 1, "failed": 0 }, "status": 200 } } ]}
4.7 ES的并发问题
常日情形下,ES在多线程操作的时候,会产生并发问题
举个例子,我跟你在淘宝在同一韶光下单买了同一本书,两个线程同时去es扣这本书的库存,库存有100本书,正常情形扣完库存后该当变成98本,但如果两个线程并发冲突,就会变成这样
可以看到库存的值变成了99本,与我们期望中的98本不符。这一征象也叫超卖,对数据库的库存扣减的时候也会涌现这种并发冲突的情形。
为掌握并发问题,我们常日采取锁机制。分为悲观锁和乐不雅观锁两种机制。
4.7.1 悲观锁悲观锁的思路是在线程1读到库存是100的时候就把es的这条库存给锁上,阻挡线程2去读库存,线程1扣完库存并把新的库存量99写入es后,才许可线程2去读取库存,这时线程2读取出来的库存是99而不是100,扣减完变成98再写入es。
这种思路实际是把并发的线程转成串行实行,非常方便,直接加锁就行,对程序来说不须要做额外的操作,但是并发能力低,同一韶光只能一条线程去扣减库存。
4.7.2 乐不雅观锁乐不雅观锁的思路是给es的库存附加一个版本号,并发冲突的情形下,线程1读取库存库存100(版本号1),线程2读取库存100(版本号1),线程1扣减库存后变成99,线程2扣减后变成99,线程1写入库存99到es前比对库存版本号(线程1读取的库存版本号为1,当前es的库存版本号为1)创造同等,于是写入库存99到es并更新库存版本号为2,线程2写入库存99到es前比对库存版本号(线程2读取的库存版本号为1,当前es的库存版本号为2)创造不一致,线程2写入失落败,线程2重新读取库存99(版本号2),线程2扣减后变成98,线程2写入库存98到es前比对库存版本号(都是2)创造同等,于是写入库存98到es并更新库存版本号为3
这种办法只是在把库存写入es那一刻检讨一下版本号判断是否可以写入就行了,不须要把库存锁上,因此并发能力很高,但这种办法编码的时候比较麻烦,每次更新库存都要去比对版本号和更新版本号,版本号对不上的时候还须要重新读取库存并扣库存。
4.7.3 ES的乐不雅观锁ES对文档的增编削都是基于版本号,也便是 _version 字段,新版本基于 _seq_no字段
多次新增同一个文档,创造版本号递增删除文档再新增,创造版本号依然递增,验证了延迟删除策略4.7.4 乐不雅观锁演示查询数据当前的版本号GET /article/_doc/7{ "_index": "article", "_type": "_doc", "_id": "10", "_version": 9, "_seq_no": 39, "_primary_term": 1, "found": true, "_source": { "title": "MySQL从入门到光头6" }}客户端1更新,带版本号PUT /article/_doc/7?if_seq_no=40&if_primary_term=1客户端2更新,带版本号,报错客户端2重新查询版本号客户端2更新,带版本号4.8 更新时的重试机制(retry_on_conflict )
有时候我们更新时,并不肯望失落败了直接报错,而是想让程序有一定的重试机制,重试一定次数后如果还是失落败,就报错,这时候可以利用 retry_on_conflict
指定重试次数
POST /index/type/_update?retry_on_conflict=次数
和_version一起利用
POST /index/type/5/_update?retry_on_conflict=3&version=22&version_type=external