`
qindongliang1922
  • 浏览: 2180719 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
7265517b-f87e-3137-b62c-5c6e30e26109
证道Lucene4
浏览量:117396
097be4a0-491e-39c0-89ff-3456fadf8262
证道Hadoop
浏览量:125814
41c37529-f6d8-32e4-8563-3b42b2712a50
证道shell编程
浏览量:59779
43832365-bc15-3f5d-b3cd-c9161722a70c
ELK修真
浏览量:71222
社区版块
存档分类
最新评论

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

    博客分类:
  • ELK
阅读更多

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



(一)更新文档

(1)部分更新:

java api:
````
`       HashMap<String,Object> data=new HashMap<>();
        data.put("name","woshigcs");
        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/test/type1/1/_update' -d '{
    "doc" : {
        "name" : "new_name"
    }
}
````





(2)使用detect_noop

java api:
````
`       HashMap<String,Object> data=new HashMap<>();
        data.put("name","woshigcs");
        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/test/type1/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","12345");
        params.put("source",data);

        StringBuffer sb_json = new StringBuffer("ctx._source=source");
        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.setUpsert(data);
        urb.execute().actionGet();
        System.out.println("更新完事。。。。。。 ");

````

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



(三):scripted_upsert用法:

官网个的例子没有跑通,下面这个是按照stackoverflow上面的例子改写的,可以通过

在postman里面已经跑通:

首先是在post请求的url

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这条数据存在不存在,如果不存在就把data里面的数据作为第一次的插入数据,如果已经存在就会把原来的数据删除掉然后把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更新的方式最强大,可以做一些复杂业务场景的操作,如数值的累增或者操作集合对象元素的追加或者删除,其他的几种方式适合简单的更新操作。

不管使用那种更新方式,我们都需要考虑并发问题,通过前面一系列的文章的介绍,我们知道es里面的更新,删除,都是伪操作,尤其是更新,在es内部的实际处理流程是:

(1)查询旧的document数据

(2)修改成最新的数据

(3)然后重建整条document


在这里的三个阶段,如果同时又另外一个进程也在修改该条数据,就会发生冲突,es里面是根据version字段来判断是否冲突的,在上面的步骤中的第一步查询旧的数据会得到version字段,在第三步时候写的时候会把这个version字段在传回,这个时候如果发现version不一致就会发生冲突然后抛出异常,所以大家在使用的时候可以优先通过设计避免多线程操作,如果实在没法避免则可以使用es里面的提供的version字段来通过乐观锁控制并发问题,如果操作是简单的累加或累减还可以用更简单的方法冲突重试来解决并发问题,一句话就是具体场景具体分析,关于es并发问题后面有空可以单独再整理一篇文章出来。


有什么问题可以扫码关注微信公众号:我是攻城师(woshigcs),在后台留言咨询。 技术债不能欠,健康债更不能欠, 求道之路,与君同行。




0
0
分享到:
评论

相关推荐

    elasticsearch数据结构设计文档

    ES 中的数据类型主要包括以下几种: * 字符串类型(string):用于存储字符串类型的数据。 * 整数类型(integer):用于存储整数类型的数据。 * 长整数类型(long):用于存储长整数类型的数据。 * 日期类型(date...

    ElasticSearch 重写IK分词器源码设置mysql热词更新词库1

    在本文中,我们将探讨如何利用Elasticsearch的IK分词器并对其进行源码改造,以实现热词库的动态更新,特别是通过MySQL数据库进行热词和停用词的定时更新。首先,我们要了解IK分词器的几种常用词库配置方式。 **0. ...

    用来实现mongodb和elasticsearch数据同步和增量更新的小程序

    在这个“aude-mongo-sync-elasticsearch-master”项目中,我们主要关注的是如何在这两个数据库之间实现数据的同步和增量更新。这通常涉及到以下几个关键知识点: 1. **数据迁移**:数据迁移是指将数据从一个数据库...

    ES客户端+谷歌浏览器插件+Multi-Elasticsearch-Head

    多弹性搜索头,对著名的 Elasticsearch Head 的改进 1.保存和存储几个Elasticsearch端点 ...它通常提供了一种直观的方式来查看索引结构、执行查询语句、分析日志数据,以及执行其他与Elasticsearch管理相关的任务。

    ES测试数据-手机.rar

    标题中的“ES测试数据-手机.rar”表明这是一个与Elasticsearch(简称ES)相关的测试数据集,主要聚焦在手机参数上。Elasticsearch是一种流行的开源全文搜索引擎,常用于复杂的数据检索、日志分析和实时数据分析。 ...

    Go-go-mysql-elasticsearch-自动同步你的MySQL数据到Elasticsearch

    标题 "Go-go-mysql-elasticsearch-自动同步你的MySQL数据到Elasticsearch" 指的是一种使用 Go 语言编写的工具,它允许你实现实时或定期地将 MySQL 数据库中的数据自动同步到 Elasticsearch 搜索引擎。这个工具名为 `...

    elasticsearch-7.17.3

    在安装和配置Elasticsearch时,需要注意的几个关键点包括: 1. 系统资源限制:确保有足够的内存和CPU资源,因为Elasticsearch是内存密集型应用。 2. 配置文件:编辑 `config/elasticsearch.yml` 文件,根据实际需求...

    使用Hbase协作器(Coprocessor)同步数据到ElasticSearch(hbase 版本 1.2.0-cdh5.8.0, es 2.4.0 版本)

    3. **连接Elasticsearch**:在Coprocessor中,使用Elasticsearch的Java API建立与ES集群的连接,创建索引和映射,然后将HBase中的数据写入相应的Elasticsearch索引。 4. **处理数据**:根据业务需求,可能需要对...

    Elasticsearch结合hbase的应用

    当Elasticsearch与Hbase结合使用时,有几种数据生成方式:定时同步、预先生成关联,同时向两边写数据;或者使用Coprocessors进行数据同步,这种方式能够保证数据在Hbase和Elasticsearch两边的一致性。Coprocessors...

    es测试数据-自制-csdn

    Elasticsearch(ES)是一种基于Lucene的分布式、RESTful搜索和分析引擎,广泛应用于大数据存储、分析和检索。在IT行业中,Elasticsearch因其高效、可扩展和易用的特性,成为许多企业的首选解决方案。"es测试数据-...

    阿里云Elasticsearch2.0发布.pdf

    阿里云推出的增强版ESLogstash as a Service提供了开箱即用的日志处理能力,使得用户可以轻松地将日志数据导入到Elasticsearch中进行实时分析和索引。这种托管式服务降低了用户自己搭建和维护Logstash环境的复杂性和...

    elasticsearch 性能测试

    常见的 Elasticsearch 性能测试工具有以下几种: 1. **JMeter**:一个开源的 Java 应用,可以创建复杂的测试计划,包括搜索、索引和数据获取操作。 2. **Bigdesk**:Elasticsearch 自带的监控工具,提供实时性能...

    spring-data-elasticsearch

    11. Spring Data REST:在Spring Data Elasticsearch中,可以结合Spring Data REST组件,通过REST API的方式提供对Elasticsearch数据的访问。 12. 异常翻译:Spring Data Elasticsearch可以将Elasticsearch的原生...

    elasticsearch监控方式-峡谷金桥

    本文将详细介绍几种常用的Elasticsearch监控方法及其实施细节。 #### 二、Elasticsearch自带监控功能 1. **ES本身监控**: - Elasticsearch提供了丰富的内部监控机制,通过这些机制可以获取集群状态、节点状态、...

    elasticsearch-7.17.9-windows-x86-64.zip

    3. **自动分片和复制**:Elasticsearch将数据分成多个碎片(shards),并自动在集群中的节点间分配,以实现高可用性和水平扩展。每个碎片还有副本(replicas),以防止数据丢失。 4. **RESTful API**:Elastic...

    ElasticSearch文档.pdf

    Java API主要分为Node方式和TransportClient方式,Node方式允许Java应用作为Elasticsearch集群中的一个节点,而TransportClient方式则是一个轻量级的客户端,可以访问Elasticsearch集群中的数据,但不参与集群的任何...

    elasticsearch-analysis-dynamic-synonym-7.12.1.zip

    在Elasticsearch中,可能用于内部通信或者数据存储。 4. **httpclient-4.5.13.jar** 和 **httpcore-4.4.13.jar**:这两个是Apache HTTP客户端库,用于处理HTTP请求和响应,可能是插件与Elasticsearch集群通信的方式...

    Elasticsearch-深入理解索引原理1

    在深入理解Elasticsearch(简称ES)的索引原理前,我们需要先明白基本概念。ES是一种分布式全文搜索引擎,它将数据存储在索引中,这些索引类似于关系型数据库中的数据库,但具备更高的可扩展性和实时性。索引可以...

Global site tag (gtag.js) - Google Analytics