Elasticsearch 创建、更新、删除文档、处理冲突
----创建新文档----
1._index,_type和_id的组合可以唯一标识一个文档,所以确保一个新文档的最简单的办法就是,使用索引请求的POST形式让elsticsearch自动生成唯一_id:
POST /website/blog
{ ... }
2.如果需要指定文档的_id,那就需要告诉elasticsearch在_index,_type和_id的组合不存在的时候进行新建操作,有两种方法实现
- 使用op_type
PUT /website/blog/123?op_type=create
{ ... }
- 在URL末端使用/_create
PUT /website/blog/123/_create
{ ... }
注意: 请求执行成功会返回元数据(执行结果)和一个201 Created 的HTTP响应码。
如果相同_index,_type和_id的组合的文档已经存在,elasticsearch将会返回409 Conflict 响应码以及如下错误信息。
{
"error": {
"root_cause": [
{
"type": "version_conflict_engine_exception",
"reason": "[blog][124]: version conflict, document already exists (current version [1])",
"index_uuid": "oCXgGtl9SfmXXD-edmYdfA",
"shard": "3",
"index": "website"
}
],
"type": "version_conflict_engine_exception",
"reason": "[blog][124]: version conflict, document already exists (current version [1])",
"index_uuid": "oCXgGtl9SfmXXD-edmYdfA",
"shard": "3",
"index": "website"
},
"status": 409
}
----删除文档----
删除文档,使用DELETE 方法:
DELETE /website/blog/123
一如果找到该文档,elasticsearch将返回一个200 ok 的HTTP响应码,和一个类似以下结构的响应体,字段_version 值会增加。
{
"found": true,
"_index": "website",
"_type": "blog",
"_id": "123",
"_version": 6,
"result": "deleted",
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
}
}
标如果文档没有找到,我们将会得到一个404 not Found 的响应码和一个类似以下结构的响应体,即便文档不存在,_version值也会增加,这是 Elasticsearch 内部记录本的一部分,用来确保这些改变在跨多节点时以正确的顺序执行。
{
"found": false,
"_index": "website",
"_type": "blog",
"_id": "123",
"_version": 3,
"result": "not_found",
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
}
}
注意:
正如已经在更新整个文档中提到的,删除文档不会立即将文档从磁盘中删除,只是将文档标记为已删除状态。随着你不断的索引更多的数据,Elasticsearch 将会在后台清理标记为已删除的文档。
----处理冲突----
多个用户对一份数据进行修改操作时,变更越频繁,读数据和更新数据的间隙越长,也就越可能丢失变更。
在数据库领域中,有两种方法通常被用来确保并发更新时变更不会丢失:
1.悲观并发控制(悲观锁)
这种方法被关系型数据库广泛使用,它假定有变更冲突可能发生,因此阻塞访问资源以防止冲突。 一个典型的例子是读取一行数据之前先将其锁住,确保只有放置锁的线程能够对这行数据进行修改。
2.乐观并发控制(乐观锁)
Elasticsearch 中使用的这种方法假定冲突是不可能发生的,并且不会阻塞正在尝试的操作。 然而,如果源数据在读写当中被修改,更新将会失败。应用程序接下来将决定该如何解决冲突。 例如,可以重试更新、使用新的数据、或者将相关情况报告给用户。
Elasticsearch 是分布式的,当文档创建,更新或者删除时,新版本的文档必须复制到集群中的其他节点。
Elasticsearch 也是异步和并发的,这意味着这些复制请求被并行发送,并且到达目的地时顺序也许是乱的。Elasticsearch 需要一种方法确保文档的旧版本不会覆盖新的版本。
可以通过_version的递增来确保变更正确的执行顺序,简单的忽略掉旧版本的文档在新版本之后到达的操作。
# 创建一个测试的文档
PUT /website/blog/1/_create
{
"title": "My first blog entry",
"text": "Just trying this out..."
}
# 得到该文档的version版本号
GET /website/blog/1
# 尝试通过重建文档的索引来保存修改,我们指定 version 为我们的修改会被应用的版本,这个操作只有在version=1的时,更新才能成功
PUT /website/blog/1?version=1
{
"title": "My first blog entry",
"text": "Starting to get the hang of this..."
}
# 更新成功后,_vetsion递增
# 重新运行相同的索引请求,仍然指定 version=1 , Elasticsearch 返回 409 Conflict HTTP 响应码
{
"error": {
"root_cause": [
{
"type": "version_conflict_engine_exception",
"reason": "[blog][1]: version conflict, current version [2] is different than the one provided [1]",
"index_uuid": "oCXgGtl9SfmXXD-edmYdfA",
"shard": "3",
"index": "website"
}
],
"type": "version_conflict_engine_exception",
"reason": "[blog][1]: version conflict, current version [2] is different than the one provided [1]",
"index_uuid": "oCXgGtl9SfmXXD-edmYdfA",
"shard": "3",
"index": "website"
},
"status": 409
}
注:所有文档的更新或删除 API,都可以接受 version 参数,这允许你在代码中使用乐观的并发控制
3.通过外部系统使用版本控制
一个常见的设置是使用其它数据库作为主要的数据存储,使用 Elasticsearch 做数据检索, 这意味着主数据库的所有更改发生时都需要被复制到 Elasticsearch ,如果多个进程负责这一数据同步,你可能遇到类似于之前描述的并发问题。
如果你的主数据库已经有了版本号 — 或一个能作为版本号的字段值比如 timestamp — 那么你就可以在 Elasticsearch 中通过增加 version_type=external 到查询字符串的方式重用这些相同的版本号, 版本号必须是大于零的整数, 且小于 9.2E+18 — 一个 Java 中 long 类型的正值。
外部版本号的处理方式和我们之前讨论的内部版本号的处理方式有些不同, Elasticsearch 不是检查当前 _version 和请求中指定的版本号是否相同, 而是检查当前 _version 是否 小于 指定的版本号。 如果请求成功,外部的版本号作为文档的新 _version 进行存储。
外部版本号不仅在索引和删除请求是可以指定,而且在 创建 新文档时也可以指定。
要创建一个新的具有外部版本号 5 的博客文章,我们可以按以下方法进行:
PUT /website/blog/2?version=5&version_type=external
{
"title": "My first external blog entry",
"text": "Starting to get the hang of this..."
}
在响应中,我们能看到当前的 _version 版本号是 5 :
{
"_index": "website",
"_type": "blog",
"_id": "2",
"_version": 5,
"result": "created",
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
},
"created": true
}
现在我们更新这个文档,指定一个新的 version 号是 10 :
PUT /website/blog/2?version=10&version_type=external
{
"title": "My first external blog entry",
"text": "Starting"
}
请求成功并将当前 _version 设为 10 :
{
"_index": "website",
"_type": "blog",
"_id": "2",
"_version": 10,
"result": "updated",
"_shards": {
"total": 2,
"successful": 2,
"failed": 0
},
"created": false
}
注:如果你要重新运行此请求时,它将会失败,并返回像我们之前看到的同样的冲突错误, 因为指定的外部版本号不大于 Elasticsearch 的当前版本号。
Elasticsearch 创建、更新、删除文档、处理冲突的更多相关文章
- 2.MongoDB系列之创建更新删除文档
1. 插入文档 // 单条插入 db.getCollection('blog').insertOne({'type': 'mongodb'}) // 批量 插入 db.getCollection('b ...
- 《mongoDB》基本操作-创建/更新/删除文档
一:基本操作 - db; 当前选择的集合(等于数据库名) > db demo - use db_name; 选择你要操作的集合 > use demo switched to db dem ...
- MongoDB(二)创建更新删除文档
插入并保存文档操作 用insert向目标集合插入文档,如果没有_id键则会自动添加.最后自动保存. >db.foo.insert({"bar":"baz" ...
- MongoDB创建\更新\删除文档操作
一.插入\创建文档 --当插入一个不存在的文档时,会自己主动创建一个文档 [root@racdb ~]# mongo MongoDB shell version: 2.4.14 connecti ...
- sharepoint中的Power Shell命令创建、删除文档库列表
ListTemplateType 枚举: 自定义列表-GenericList.文档库-DocumentLibrary.图片库-PictureLibrary.公告-Announcements.联系人-C ...
- Elasticsearch 删除文档
章节 Elasticsearch 基本概念 Elasticsearch 安装 Elasticsearch 使用集群 Elasticsearch 健康检查 Elasticsearch 列出索引 Elas ...
- Elasticsearch 使用集群 - 创建和查询文档
章节 Elasticsearch 基本概念 Elasticsearch 安装 Elasticsearch 使用集群 Elasticsearch 健康检查 Elasticsearch 列出索引 Elas ...
- elasticsearch 第五篇(文档操作接口)
INDEX API 示例: 1 2 3 4 5 PUT /test/user/1 { "name": "silence", "age": 2 ...
- 详细描述一下 Elasticsearch 更新和删除文档的过程?
1.删除和更新也都是写操作,但是 Elasticsearch 中的文档是不可变的,因此不 能被删除或者改动以展示其变更: 2.磁盘上的每个段都有一个相应的.del 文件.当删除请求发送后,文档并没有真 ...
随机推荐
- 《高级软件测试》web测试实践--12月30日记录
考完数学,我们正式开始web测试实践的作业,今天,我们主要进行了方案的选择和人员的分工.任务计划和安排如上图所示. 任务进展:完成题目选择和人员分工: 遇到问题:暂无: 下一步任务:完成软件评测.用户 ...
- JAVA_SE基础——12.运算符的优先级
优先级 操作符 含义 关联性 用法 ---------------------------------------------------------------- 1 [ ] 数组下标 左 arra ...
- 使用cxf创建webservice 出现timeOut的问题,设置spring超时时间
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- 初次面对c++
第一次实验 2-4源码: #include<iostream> using namespace std; int main() { int day; cin>>day; swi ...
- JSON(三)——java中对于JSON格式数据的解析之json-lib与jackson
java中对于JSON格式数据的操作,主要是json格式字符串与JavaBean之间的相互转换.java中能够解析JSON格式数据的框架有很多,比如json-lib,jackson,阿里巴巴的fast ...
- python flask框架 数据库的使用
#coding:utf8 from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) # ...
- mysql的账户管理
mysql中账户管理:1 查看所有用户: 所有用户及权限信息都存储在mysql数据库中的user表中 查看user表的结构 desc user\G; 主要字段: host: 表示允许访问的主机 use ...
- Django—中间件
中间件简介 什么是中间件 中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于在全局范围内改变Django的输入和输出.每个中间件组件都负责做一些特定的功 ...
- python 类知识点总结
python 类知识点总结 面向对象思想: 1.设计的时候,一定要明确应用场景 2.由对象分析定义类的时候,找不到共同特征和技能不用强求 1.简述类.对象.实例化.实例这些名词的含义: 类:从一组对象 ...
- 算法 排序lowB三人组 冒泡排序 选择排序 插入排序
参考博客:基于python的七种经典排序算法 [经典排序算法][集锦] 经典排序算法及python实现 首先明确,算法的实质 是 列表排序.具体就是操作的列表,将无序列表变成有序列表! 一 ...