背景
源于一个不认真看elasticsearch的误会,有新需求需要用到es的BULK API中的update方法。使用这个方法,加入更新的文档没有变更(即更新前后是一样的)默认不会更新,result返回noop,version等均不会被更新(可以理解为mysql的upsert)。
先创建一条数据:
POST _bulk { "index" : { "_index" : "test", "_id" : "1" } } { "field1" : "value1" }
误会来自于以下操作:
POST _bulk { "update" : {"_id" : "1", "_index" : "test"} } { "doc" : {"field2" : "value2"} }
POST _bulk { "index" : {"_id" : "1", "_index" : "test"} } { "doc" : {"field2" : "value2"} }
POST _bulk { "update" : {"_id" : "1", "_index" : "test"} } { "doc" : {"field2" : "value2"} }
POST _bulk { "update" : {"_id" : "1", "_index" : "test"} } { "doc" : {"field2" : "value2"} }
连续执行以上语句,第一次是返回noop,第二次返回updated,第三次返回updata的,第四次返回noop
问题在于为什么第三次返回updated而不是noop呢?
查了好久资料没发现,看源码也没发现。只是有很多if else分支,怀疑是否某个条件不满足所有被updated,遂自己debug源码找答案。
调试环境搭建
1.下载源码,并导入eclipse。具体可直接看es git的https://github.com/elastic/elasticsearch/blob/master/CONTRIBUTING.md,里面有介绍说明。
2.在docker上跑起ES,注意需要与源码分支版本一致,本次使用7.14分支。
<pre class="brush:bash;">#拉取镜像
docker pull docker.io/elasticsearch:7.14.0
查看镜像id
docker image|grep elastic
找出IDrun起来,加上远程debug参数
docker run -d --name es7.14 -p 9200:9200 -p 9300:9300 -p 5678:5678/tcp -e "discovery.type=single-node" -e ES_JAVA_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=0.0.0.0:5678" e347b2b2d6c1
3.eclpise连接远程

eclipse.jpg
debug过程

debug.jpg
被update的原因在与key是不一样的,一个是{doc={field2=value2}},一个是field2=value2
发现原来doc在index跟update含义是不一样的。在index会当成key操作,在update是关键字,里面内容才是更新的map

doc.jpg