关于ElasticSearch中更新数据的几种方式

首先给大家推荐一下我老师大神的人工智能教学网站。教学不仅零基础,通俗易懂,而且非常风趣幽默,还时不时有内涵黄段子!点这里可以跳转到网站

作为一个成熟的框架,ElasticSearch里面提供了丰富的操作数据的api,本篇是用来学习一下es中更新数据的几种方式。

一、更新文档

1:部分更新:

Java api

`       HashMap<String,Object> data=new HashMap<>();        data.put("name","helloES");        data.put("age",25);        UpdateRequestBuilder urb= client.prepareUpdate("active2018-03-21", "active", "18");        urb.setDoc(data);        urb.execute().actionGet();         System.out.println("update ok......");

注意部分更新功能,前提是索引和该条数据已经存在,否则会抛出对应的异常,只要任何一个不满足,都会更新失败。

curl

curl -XPOST 'localhost:9200/index/type/1/_update' -d '{    "doc" : {        "name" : "new_name"    }}

(2)使用detect_noop

java api:

`       HashMap<String,Object> data=new HashMap<>();        data.put("name","helloES");        data.put("age",25);        UpdateRequestBuilder urb= client.prepareUpdate("active2018-03-21", "active", "18");        urb.setDoc(data);        urb.setDetectNoop(false);//默认是true        urb.execute().actionGet();         System.out.println("update ok......");

curl方式:

curl -XPOST 'localhost:9200/index/type/1/_update' -d '{    "doc" : {        "name" : "new_name"    },    "detect_noop": false}'

注意detect_noop 的意思:

默认情况下detect_noop =true

默认情况下只有原来的source和新的source存在不同的字段情况下才会重建索引,如果一模一样是不会触发重建索引的,如果将detect_noop=false不管内容有没有变化都会重建索引,这一点可以通过version的值的变化来发现更新的文档,必须提前存在,除非你用upset+script来更新,否则会报document missing异常。

二、script+upset更新方式

java api

HashMap<String,Object> params=new HashMap<>();

HashMap<String,Object> data =new HashMap<>();

data.put(“name”,”helloES”);

params.put(“source”,data);

StringBuffer sb_json=new StringBuffer(“ctx._source=source”);

Script script=new Script(sb_json.toString(),ScriptService.ScriptType.INLINE,”groovy”,params);

UpdateRequestBuild urb=client.prepareUpdate(“active2018-03-31″,”active”,”16″);

urb.setScript(script);

urb.setUpsert(data);

urb.execute().actionGet();

System.out.println(“success”);

curl

curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{    "script" : {        "inline": "ctx._source.counter += count",        "params" : {            "count" : 4        }    },    "upsert" : {        "counter" : 1    }}'

三、scripted_upsert用法:

java api:

`       HashMap<String,Object> params=new HashMap<>();        HashMap<String,Object> data=new HashMap<>();        data.put("name","12345");         HashMap<String,Object> newdata=new HashMap<>();        newdata.put("name","789");         params.put("data",data);        params.put("newdata",newdata);          StringBuffer sb_json = new StringBuffer("if (ctx.op == \"create\") ctx._source=data; else ctx._source=newdata");        Script script = new Script(sb_json.toString(), ScriptService.ScriptType.INLINE, "groovy", params);        UpdateRequestBuilder urb= client.prepareUpdate("active2018-03-11", "active", "16");        urb.setScript(script);        urb.setScriptedUpsert(true);        urb.setUpsert("{}");//必须有这个值,否则会报document missing exception        urb.execute().actionGet();        System.out.println("更新完事。。。。。。 ");

curl方式

http://192.168.201.5:9200/active2018-03-11/active/11/_update

然后是下面的body里面选择raw然类型是JSON(application/json):

{    "scripted_upsert":true,    "script" : {        "script":"if (ctx.op == \"create\") ctx._source=data; else ctx._source=newdata ",        "params" : {            "data":{                "ct":11,                "aid":"a22",                "tid":"t11"            },            "newdata":{                "ct":1000,                "aid":"a2qq2",                "tid":"qq"            }        }            },    "upsert" : {}}

执行上面的脚本,首先要检查索引是否存在,如果不存在就会新建一个索引,然后会判断id等于11这条数据存不存在,如果不存在就把打他里面的数据作为第一次插入的数据,如果已经存在就会把原来的数据删除掉然后把newdata的数据插入进去,可以理解就是更新。这里需要注意,如果用的是动态mapping,需要注意数据的类型,动态mapping下两条数据里面的同一个字段拥有不同的类型,这样既灵活又带来了风险,所以对于严禁类型的数据推荐使用静态mapping,严格限定字段的类型。

四、doc_as_upsert方式:

这个方式其实就是前面两个简洁版,意思就是没有就插入又就覆盖,注意这是覆盖不是把原来的删除再擦插入,而且如果是mapping还可以改变字段的类型,但不建议这么用。

java api:

`       HashMap<String,Object> data=new HashMap<>();        data.put("name","234");        data.put("age",123);        data.put("address","北京海淀区");        UpdateRequestBuilder urb= client.prepareUpdate("active2018-03-11", "active", "16");        urb.setDoc(data);        urb.setDocAsUpsert(true);         urb.execute().actionGet();//        System.out.println("操作成功......");

curl方式:

http://192.168.201.5:9200/active2018-03-11/active/12/_update{    "doc" : {        "name" : "6755",        "age":12,        "address":"北京朝阳"            },    "doc_as_upsert" : true}

总结:

上面的更新操作es的几种方法,总体来说使用script更新的方式跟强大,可以做一些复杂业务场景的操作,如数值发的累增或者操作集合对象元素的追加或者删除,其他的几种方式适合简单的更新操作。

点这里可以跳转到人工智能网站

发表评论