----创建新文档----

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 创建、更新、删除文档、处理冲突的更多相关文章

  1. 2.MongoDB系列之创建更新删除文档

    1. 插入文档 // 单条插入 db.getCollection('blog').insertOne({'type': 'mongodb'}) // 批量 插入 db.getCollection('b ...

  2. 《mongoDB》基本操作-创建/更新/删除文档

    一:基本操作 - db; 当前选择的集合(等于数据库名) > db demo -  use db_name; 选择你要操作的集合 > use demo switched to db dem ...

  3. MongoDB(二)创建更新删除文档

    插入并保存文档操作 用insert向目标集合插入文档,如果没有_id键则会自动添加.最后自动保存. >db.foo.insert({"bar":"baz" ...

  4. MongoDB创建\更新\删除文档操作

     一.插入\创建文档 --当插入一个不存在的文档时,会自己主动创建一个文档 [root@racdb ~]# mongo MongoDB shell version: 2.4.14 connecti ...

  5. sharepoint中的Power Shell命令创建、删除文档库列表

    ListTemplateType 枚举: 自定义列表-GenericList.文档库-DocumentLibrary.图片库-PictureLibrary.公告-Announcements.联系人-C ...

  6. Elasticsearch 删除文档

    章节 Elasticsearch 基本概念 Elasticsearch 安装 Elasticsearch 使用集群 Elasticsearch 健康检查 Elasticsearch 列出索引 Elas ...

  7. Elasticsearch 使用集群 - 创建和查询文档

    章节 Elasticsearch 基本概念 Elasticsearch 安装 Elasticsearch 使用集群 Elasticsearch 健康检查 Elasticsearch 列出索引 Elas ...

  8. elasticsearch 第五篇(文档操作接口)

    INDEX API 示例: 1 2 3 4 5 PUT /test/user/1 { "name": "silence", "age": 2 ...

  9. 详细描述一下 Elasticsearch 更新和删除文档的过程?

    1.删除和更新也都是写操作,但是 Elasticsearch 中的文档是不可变的,因此不 能被删除或者改动以展示其变更: 2.磁盘上的每个段都有一个相应的.del 文件.当删除请求发送后,文档并没有真 ...

随机推荐

  1. 码农、黑客和2B程序员之间的区别

    码农: 黑客: 2B程序员: 求2的32次方: 码农: System.out.println(Math.pow(2, 32)); 黑客: System.out.println(1L<<32 ...

  2. UML开发工具Rose ralation的破解安装,

    UML开发工具Rose ralation的在windows764破解安装, 安装下载还可以参考:http://www.cnblogs.com/leaven/p/3718361.html 跟大家分享怎么 ...

  3. token 验证

    组件: https://jwt.io/#libraries-io

  4. jquery 实时监听输入框值变化方法

    $('.offers-number').bind('input propertychange', function (a, b) { var value = $(this).val() if (!va ...

  5. SpringCloud的服务注册中心(四)- 高可用服务注册中心的搭建

    一.双 服务注册注册中心 1.服务注册中心的服务端 - EurekaServer 1.1.EurekaServer1 String.application.name=eureka-server ser ...

  6. linux下的Shell编程(3)shell里的流程控制

    if 语句 if 表达式如果条件命令组为真,则执行 then 后的部分.标准形式: if 判断命令,可以有很多个,真假取最后的返回值 then 如果前述为真做什么 [ # 方括号代表可选,别真打进去了 ...

  7. C# bootstrap之表格动态绑定值

    这段时间研究了下bootstrap,打算从表格开始学习,实现动态绑定值,在网上找了挺多例子,但是很少有写全的,要不就太复杂,实现效果后总结一下,直接拷贝过去可以用. 第一步:先去官网上下载bootst ...

  8. SpringBoot 分布式session

    SpringBoot 分布式session实现 1. 什么是分布式session 在集群环境中,不得不考虑的一个问题是用户访问产生的session如何处理.如过不做任何处理,用户将出现频繁俸禄的现象, ...

  9. leetcode算法: Find Largest Value in Each Tree Row

    '''You need to find the largest value in each row of a binary tree.Example:Input: 1 / \ 3 2 / \ \ 5 ...

  10. 未能加载文件或程序集“ RevitAPIUI.dll”

    revit二次开发中遇到的问题 RevitAPIUI.dll 只能 Native Library 中执行: 脱离了Native Library,API是跑不起来的 . 检查程序流程:登录,配置,启动r ...