ElasticStack系列之十九 & bulk时 index、create 和 update 的区别
index/create
第一步判断是确定插入的文档是否指定id,如果没有指定id,系统会默认生成一个唯一id。
这种情况下,不管index还是create会直接add文档。如果用户指定了id,那么就会走update,update成本比add要高。
第二步判断,会检查版本号是否冲突,只有正确的版本号才会执行插入,否则会插入失败。
通过源码分析可以了解到,获取版本号的这个过程,是通过id来get文档,但无论是index还是create都不会get整个doc的全部内容,只是get出了版号。这也从一定程度上减少了系统开销。
总结:
<1. 自动生成的 id,则 index/create 都采用 add 方式
<2. 业务指定的 id,则 index/create 都采用 update 方式
<3. 检查版本号是否冲突
update
由于 Lucene 中的 update 其实就是覆盖替换,并不支持针对特定 Field 进行修改,Elasticsearch 中的 update 为了实现针对特定字段修改,在 Lucene 的基础上做了一些改动。
每次 update 都会调用 InternalEngine 中的 get 方法,来获取整个文档信息,从而实现针对特定字段进行修改,这也就导致了每次更新要获取一遍原始文档,性能上会有很大影响。
所以根据使用场景,有时候使用 index 会比 update 好很多。
index和create区别
index 和 create 都会检查 _version 版本号。
index 插入时分两种情况:
<1. 没有指定 _version,那对于已有的doc,_version会递增,并对文档覆盖。
<2. 指定_version,如果与已有的文档 _version 不相等,则插入失败;如果相等则覆盖,_version递增。
create 插入时对于已有的文档,不会创建新文档,即插入失败,会抛出一个已经存在的异常。
用途解释:
在批量请求的时候最好使用 create 方式进行导入。假如你批量导入一个大小为500MB 的文件,中途突然网络中断,可能其中有5万条数据已经导入,那么第二次尝试导入的时候,如果选用 index 方式,那么前5万条数据又会重复导入,增加了很多额外的开销,如果是 create 的话,elasticsearch 针对 bulk 操作机制是忽略已经存在的(当然在 bulk 完成后会返回哪些数据是重复的),这样就不会重复被导入了