Elasticsearch 索引文档时create、index、update的区别【学习记录】

本文基于elasticsearch7.3.0版本。

一、思维导图

elasticsearch中create、index、update都可以实现插入功能,但是实现原理并不相同。

在这里插入图片描述

二、验证index和create

由上面思维导图可以清晰的看出create、index的大致区别,下面我们来验证下思维导图中的场景:

1、首先明确一点:如何指定是create操作还是index操作?可以通过在ES DSL指令后面拼接op_type=create_create实现。

例:假设目前我有一个索引为my_index,现在要向ES中索引一条doc,并指定是create操作:

POST my_index/_doc/1?op_type=create
{"tag":"指定id为1,并指定为create操作"
}
# 上面请求等价于
POST my_index/_doc/1/_create
{"tag":"指定id为1,并指定为create操作"
}

声明:文章后面内容中,所有演示的指令均省略了后面具体doc的内容,请知悉,如下图所示。
在这里插入图片描述


2、思考并验证:当向ES中索引一条doc,执行对应DSL指令时,ES底层默认触发什么操作?

场景1)向ES中索引一条数据,没有指定id,执行指令POST my_index/_doc时:

当您在指令中不提供文档ID时,Elasticsearch会自动生成一个唯一的文档ID,并使用该ID进行create操作。

场景2)向ES中索引一条数据,指定的id不存在,执行指令POST my_index/_doc/1(doc id为1的文档不存在)时:

当您在指令中指定的文档ID不存在时,则会使用指定的文档ID来执行create操作。

场景3)向ES中索引一条数据,指定了id并且id存在,执行指令POST my_index/_doc/1(doc id为1的文档存在)时:

当您在指令中指定的文档ID已经存在时,则会使用指定文档ID来执行index操作,更新该文档。这是因为index操作在存在相同文档ID时会执行更新操作(版本号在原有基础上+1),而不是创建新文档。

场景4.)向ES中索引一条数据,指定了id并且id存在,并指定了版本号,执行指令POST my_index/_doc/1?version=7&version_type=external时:

上述指令在Elasticsearch中,假设ID为1的文档已经存在,则会执行Elasticsearch的index操作。

在这个请求中,通过指定version参数为7和version_type参数为external,您告诉Elasticsearch在执行index操作时,将指定的版本号与文档的当前版本号进行比较。如果指定的版本号与当前版本号符合匹配规则,则会执行更新操作,否则会返回版本冲突错误。

补充:DSL中如何指定一个版本号?POST my_index/_doc/1?version=7&version_type=external_gte

  • version:外部指定版本号
  • version_type:外部版本号校验类型,有两种:external(默认,外部版本号必须要大于内部版本号),external_gte(外部版本号大于等于内部版本号)

注意:如果DSL指令如果指定了版本号,那么必须指定doc id,否则会报错。

3、下面我们演示思维导图中几种执行报错的场景:

场景1)执行create操作时,指定doc id并且id存在时,会报错。执行POST my_index/_doc/1?op_type=create指令,执行结果如下:[1] :版本冲突,文档已存在(当前版本[7])
在这里插入图片描述

场景2)执行create操作时,指定外部版本号时,会报错。那么执行POST my_index/_doc/1?op_type=create&version=8&version_type=external指令,执行结果如下:验证失败:1:创建操作仅支持内部版本控制。改为使用索引;
在这里插入图片描述

场景3)通过index更新数据时,指定的外部版本号没有超过当前版本号时,会报错。

先执行GET my_index/_doc/1指令,查看doc id为1的数据对应的version,可以看到id为1的doc,version为7。
在这里插入图片描述
当我们执行指令POST my_index/_doc/1?version=7&version_type=external时(指定了版本号没有指定op_type时,默认就是index操作),执行结果如下:[1] :版本冲突,当前版本[7]高于或等于提供的版本[7]
在这里插入图片描述

三、index和create小结

  1. 执行DSL指令,不指定文档id或指定文档id不存在时,系统会默认生成一个唯一的id,执行create操作,索引一个新文档;
  2. 执行DSL指令,指定了doc id并且存在时,默认执行index操作,会执行更新操作而不是索引新文档(如果此处显示的指定了create操作会报错);
  3. 执行DSL指令,指定了doc id并且存在时,默认执行index操作,如果此时又指定了外部版本号又显示指定操作类型为create,由于create操作只支持内部版本控制,会报错;
  4. 执行DSL指令,指定了doc id并且存在,同时又指定了外部版本号,此时指定的外部版本号必须大于或大于等于当前版本号,否则会执行错误。

四、update操作

在Elasticsearch的DSL指令中,可以使用以下方式来更新文档:

1、使用update指令:update指令用于更新指定文档的内容。更新可以是部分更新或完整替换,具体取决于您提供的更新内容。下面是一个示例:

其中,index_name是索引名称,doc_id是要更新的文档ID,field1是要更新的字段名称,new_value是要更新的字段值。

POST /index_name/_update/doc_id
{"doc": {"field1": "new_value"}
}

使用doc_as_upsert参数:如果要更新的文档doc_id不存在,您可以通过设置doc_as_upsert参数为true来执行全量覆盖操作。此时Elasticsearch会将doc参数中的内容作为新文档插入索引。下面是一个示例:

POST /index_name/_update/doc_id
{"doc": {"field1": "new_value"},"doc_as_upsert": true
}

2、使用update_by_query指令:update_by_query指令用于根据查询条件批量更新文档。您可以在查询条件中指定要更新的文档范围,然后提供要进行更新的内容。下面是一个示例:

POST /index_name/_update_by_query
{"query": {"match": {"field1": "value"}},"script": {"source": "ctx._source.field1 = 'new_value'"}
}

除了上述示例中的方式,还可以使用其他的更新方式,如通过script脚本来指定更新逻辑,或者使用upsert选项来指定如果文档不存在时要执行的操作。

请注意,具体的更新语法和选项可能会因Elasticsearch的版本而有所不同。建议参考官方文档或特定版本的API文档以获取准确的语法和选项。

五、index和update小结

1、在Elasticsearch中,如何选择使用index还是update进行doc更新?

  • index操作:使用index操作时,无论文档是否已存在,都会将提供的文档数据进行索引。如果指定的文档ID已存在,将会更新该文档的内容。这意味着index操作既可以用于创建新文档,也可以用于更新现有文档。

  • update操作:使用update操作时,可以对现有文档进行部分更新,而不是替换整个文档。通过update操作,您可以指定要应用的更新脚本或部分文档,以及如何更新现有文档的字段。这种方式更适合于需要对文档进行增量更新的情况。

因此,您可以根据具体的需求来选择使用index操作还是update操作。如果您希望完全替换文档或创建新文档,可以使用index操作。如果您只需要对文档的部分内容进行更新,可以选择update操作。

2、Elasticsearch的update和Lucene的update有哪些区别?

  • 粒度不同:Lucene的update操作是底层索引库的操作,它以文档为单位进行更新。而Elasticsearch的update操作是在更高级别的抽象上进行的,可以对文档的部分内容进行更新。

  • 更新方式不同:Lucene的update操作是通过先删除原始文档,再插入新文档来实现更新。而Elasticsearch的update操作可以通过使用更新脚本、部分文档或者提供的更新内容,对现有文档进行增量更新。

  • 并发处理不同:Lucene的update操作是在单个节点上执行的,不支持分布式并发更新。而Elasticsearch的update操作是分布式的,可以在多个节点上并发执行更新操作。

  • 功能扩展性不同:Elasticsearch的update操作提供了更丰富的功能和灵活性,如支持脚本更新、条件更新、局部更新等。而Lucene的update操作相对较为基础,功能较为有限。

总的来说,Lucene的update操作是底层索引库的原子操作,而Elasticsearch的update操作是在Lucene之上进行的更高级别的操作,提供了更多的功能和灵活性,适用于分布式环境下的文档更新需求。

3、ES 的DSL指令什么时候会使用Lucene的更新操作?

在Elasticsearch的DSL指令中,并不会直接使用Lucene的更新操作。Elasticsearch的DSL指令是在更高级别的抽象上操作的,当您使用Elasticsearch的DSL指令(如update、update_by_query等)来更新文档时,Elasticsearch解析DSL指令,并根据指令中提供的更新内容,在内部生成相应的Lucene更新操作。

虽然在DSL指令中没有直接使用Lucene的更新操作,但是Elasticsearch底层的引擎是基于Lucene的,它会利用Lucene的功能来实现文档的更新。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/621588.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

照片删除了怎么恢复回来

照片,对我们来说,这两个字眼再熟悉不过了,每一张照片都包含无比重要的意义,相信在大家的心目中,这些包含意义的照片都是无价的。怎样找回删除的照片? 既然这些照片对我们来说意义非凡,那如果不小…

通过 C++/WinRT 实现高级并发和异步

将工作卸载到 Windows 线程池 协同例程与任何其他函数的类似之处在于,调用方将会阻塞到某个函数向其返回了执行为止。 另外,协同例程返回的第一个机会是第一个 co_await、co_return 或 co_yield。 因此,在协同例程中执行受计算限制的工作之…

使用Guava Retrying优雅的实现业务异常重试

上次写过一篇如何使用spring retry来实现业务重试的文章:https://blog.csdn.net/Kingsea442/article/details/135341747 尽管 Spring Retry 工具能够优雅地实现重试,但它仍然存在两个不太友好的设计: 重试实体被限定为 Throwable 子类&#…

c++多久会被Python或者新语言取代?

c多久会被Python或者新语言取代? 在开始前我有一些资料,是我根据网友给的问题精心整理了一份「c的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!&am…

方法重写。

altinsert 静态方法和非静态方法不一样 重写只与非静态方法有关 重载是指在一个类中定义多个同名的方法或者函数,但是这些方法或者函数的参数列表不同,即参数的类型、个数或者顺序不同。当调用这个同名方法或者函数时,编译器会根据实际传入的…

Elasticsearch的基本功能和使用

Elasticsearch ,简称为 ES,是一款非常强大的开源的高扩展的分布式全文 检索引擎,可以帮助我们从海量数据中快速找到需要的内容,它可以近乎实时的 存储、检索数据.还可以可以实现日志统计、分析、系统监控等功能. 官网:https://www.elastic.c…

QT+jenkins window环境实现一键自动化构建打包签名发布

jenkins + QT 自动化构建打包 1.官网下载地址: Jenkins download and deployment,下载最新版本的安装包并安装。安装过程中,会要求你输入端口号并记住。 2.java下载地址:Java Downloads | Oracle,下载最新版本的安装包并安装。 3.浏览器输入网址:127.0.0.1: port, port为…

【Docker】镜像的构建与上传下载阿里云

🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的专栏《Docker实战》。🎯🎯 &…

C++ Primer 6.4 函数重载 知识点+练习题

C Primer 6.4 函数重载 定义重载函数重载和const形参const_cast和重载重载与作用域练习题 定义重载函数 void lookup(int a); void lookup(double b); void lookup(int a,double b); 此三个函数构成函数重载,具体调用时根据传入实参进行匹配void lookup(int a); bo…

【iOS】UIColor、CGColor、CIColor的区别和联系

编者在实验室小组的指导下,仿写了许多App,其中UI的颜色模仿也是令人头痛的点。设计颜色一般使用UIColor类方法直接获取颜色: 有时会使用 (UIColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alph…

C++中什么时候应该使用结构体,什么时候应该使用类

第一点: 在C中,结构体和类都可以用来定义自定义数据类型, 它们之间的主要区别在于默认的访问控制和成员变量的默认初始化方式。 结构体: - 结构体的成员变量默认为public访问权限。 - 结构体的成员变量默认为公共可见的&#x…

代码随想录算法训练营day8|344.反转字符串、541.反转字符串II、54.替换数字、151.翻转字符串里的单词、55.右旋转字符串

344.反转字符串 541. 反转字符串II 卡码网:54.替换数字 151.翻转字符串里的单词 卡码网:55.右旋转字符串 344.反转字符串 建议: 本题是字符串基础题目,就是考察 reverse 函数的实现,同时也明确一下 平时刷题什么时候用…

权限修饰符-面向对象——java学习笔记

什么是权限修饰符? 用来限制类中的成员(成员变量、成员方法、构造器、代码块...)能够被访问的范围 各权限修饰符的限制范围: 修饰符在本类中同一个包下的其他类里任意包下的子类里任意包下的任意类里private√缺省√√protec…

2023.1.13 关于在 Spring 中操作 Redis 服务器

目录 引言 前置工作 前置知识 实例演示 String 类型 List 类型 Set 类型 Hash 类型 ZSet 类型 引言 进行下述操作的前提是 你的云服务器已经配置好了 ssh 端口转发即已经将云服务器的 Redis 端口映射到本地主机 注意: 此处我们配置的端口号为 8888 可点击下…

jmeter如何做接口测试?

Jmeter介绍&测试准备: Jmeter介绍:Jmeter是软件行业里面比较常用的接口、性能测试工具,下面介绍下如何用Jmeter做接口测试以及如何用它连接MySQL数据库。 前期准备:测试前,需要安装好Jmeter以及jdk并配置好jdk环…

小知识分享2

文章目录 1.TCP/IP协议2.四次挥手断开连接3.TCP的三次握手和四次挥手4.在什么情况下需要设置WINS Proxy?5.用户与用户账户有什么不同?为什么需要使用用户账户? 1.TCP/IP协议 1、TCP/IP、Transmission Control Protocol/internet Protocol,传…

杨中科 EFCORE 第三部分 主键

主键 自增主键 1、EF Core支持多种主键生成策略:自动增长;Guid;Hi/Lo算法等。 2、自动增长。 优点:简单; 缺点: 数据库迁移以及分布式系统中(多数据库合并,会有重复主键值)比较麻烦;并发性能差(大并发情况下,为了保证…

函数栈桢的创建和销毁

函数栈桢的创建和销毁 一、解决的问题二、认识常用的寄存器及其指令操作三、函数栈桢解析三、回答问题 一、解决的问题 1.局部变量是怎么创建的?  2.为什么局部变量的值是随机值?  3.函数是怎么传参的?传参的顺序是怎样的?  4.…

python24.1.14while循环

当条件结束时间未知时,while循环比for循环更合适 实践

Vue 3面试题

Vue 3面试题 以下是一些常见的Vue 3面试题: Vue 3中的Composition API是什么?它与Options API有什么区别? 答案: Composition API是Vue 3中引入的一种新的组件设计模式,它允许开发者通过函数的形式组织和重用组件的逻…