【ElasticSearch系列连载】7. 关于ES数据读写那点事儿

2023-10-29

1 对文档建索引

1.1 自定义文档ID

如果数据本身有自己的唯一标记,那么在建立索引时可以使用id来指定文档的id。

如下,使用curl在your_index索引下写入一个id=1001的文档。

curl -H "Content-Type: application/json" -XPOST 'http://es00:9200/your_index/_doc/1001' -d '
{
    "field": "内容"
}
'

返回如下

{
    "_index": "your_index",
    "_type": "_doc",
    "_id": "1001",
    "_version": 1,
    "result": "created"
}

可以看到除了index, type和id字段,还有一个version字段。

在ES中每个文档都有一个自己的version编号,每当文档发生变化时,version就会增长。

1.2 使用自增ID

如果文档没有唯一标识,也可以让ES帮你自动生成文档ID,对应请求的方式也要发生变化:使用POST方法。

curl -H "Content-Type: application/json" -XPOST 'http://es00:9200/your_index/_doc' -d'
{
    "field": "内容"
}
'

会自动生成一个id,使用base64编码的UUID。

{
    "_index": "your_index",
    "_type": "_doc",
    "_id": "cZeQEYIBJnF0z3Du5UvX",
    "_version": 1,
    "result": "created"
}

2 获取文档

使用GET请求获取id为1001的文档。

http://es00:9200/your_index/_doc/1001?pretty

返回的数据体在_source字段中。

如果你查找的文档不存在,found字段会变为false(同时返回的HTTP状态码为404)。

{
  "_index" : "your_index",
  "_type" : "_doc",
  "_id" : "1001",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "field" : "内容"
  }
}

3 只获取文档的部分字段

正常情况下GET请求会将文档的所有字段都进行返回。但如果你只需要部分字段的话,可以通过在URL中使用_source参数来控制需要返回的字段。

http://es00:9200/your_index/_doc/1001?pretty&_source=field

_source中只包含了需要的字段部分。

{
  "_index" : "your_index",
  "_type" : "_doc",
  "_id" : "1001",
  "_version" : 1,
  "found" : true,
  "_source" : {
    "field" : "内容"
  }
}

如果只是想要获取数据体而不需要其他辅助信息,那么使用_source即可。

http://es00:9200/your_index/_doc/1001/_source

返回如下,直接是数据体

{
    "field": "内容"
}

4 文档更新

首先,文档数据在ES中是不可修改的。所以当我们需要对一个已有的文档进行更新时,会自动进行如下的系列操作:

  1. 获取要更新的文档
  2. 根据修改请求对其在临时存储中进行修改
  3. 删掉要更新的文档
  4. 重建文档

即:先删除,再新建

请求方式和新建文档一样。

curl -H "Content-Type: application/json" -XPOST 'http://es00:9200/your_index/_doc/1001' -d '
{
    "field": "内容"
}
'

返回如下

{
    "_index": "your_index",
    "_type": "_doc",
    "_id": "1001",
    "_version": 1,
    "result": "created"
}

5 创建全新文档

如果我们只希望在文档不存在时新建文档,而不是无条件覆盖的话,可以在请求时添加_create,这样的话,如果这个文档id已经存在则不会新建成功。

比如请求如下,仍然新建id为1001的文档。

curl -H "Content-Type: application/json" -XPOST 'http://es00:9200/your_index/_doc/1001/_create' -d '
{
    "field": "内容"
}
'

返回如下,409

{
    "error": {
        "type": "version_conflict_engine_exception",
        "reason": "[1001]: version conflict, document already exists (current version [2])",
        "index_uuid": "a9ZncSd_TJWK411z1Bb76g",
        "shard": "0",
        "index": "your_index"
    },
    "status": 409
}

6 删除文档

进行如下DELETE请求即可进行id=1001的文档删除操作。

curl -XDELETE 'http://es00:9200/your_index/_doc/1001'

如果文档存在,返回如下(deleted)

{
    "_index": "your_index",
    "_type": "_doc",
    "_id": "1001",
    "_version": 3,
    "result": "deleted"
}

如果文档不存在,返回如下(not_found, 404)

{
    "_index": "your_index",
    "_type": "_doc",
    "_id": "1001",
    "_version": 3,
    "result": "not_found"
}

7 处理冲突

如上文所述,如果我们要更新一个文档,需要先读取到原始的文档,对其进行临时修改,然后重新新建这个文档。

即:如果两个人同时获取 & 修改文档,谁最后修改,谁的就生效。

大部分情况下都不影响:

  1. 比如数据是从关系型数据库同步过来的,无所谓冲突
  2. 比如虽然两个人都是修改,但就是按照先后顺序就好了,业务上可以承受另一个人的修改不生效

但是有时候就会影响,比如售卖一个东西,如图

两个人同时购买时,两个网站此时获取到的库存都是100,购买时两个网站都试图将100减一变成99,一起更新,最后的库存变成99(应该是98)。

不难发现,当更新变动的频率越快,以及读取数据到更新数据的周期越长时,就越容易出现上面问题。

在大数据的领域,通常有两种方式保障并发更新的正确性。

  1. 悲观并发控制

    这个是关系型数据库广泛使用的,假设冲突修改会经常发生,所以会很严格的控制对数据资源的访问来防止冲突的发生。比如:在读取数据时会将目标数据上锁,确保只有这个线程可以修改这条数据,期间其他线程无法对这条数据进行操作

  2. 乐观并发控制

    也是ES使用的并发控制模式。这种模式假设冲突不经常发生,所以在尝试数据修改时不会加锁、不会阻碍其他线程对数据的访问。但是,如果在读取到更新期间发现数据有过更新记录,则可以阻止这次的更新操作并报错。剩下的交给调用方去判断:是继续使用新的数据再来一次更新

8 文档版本控制

ES是一个分布式系统,所以当一个文档发生变化时,ES需要将这个文档的变化推送到各个节点中去,这个过程是并发的,所以ES需要有一个机制保证一个文档的旧版本不会覆盖新版本。通过在更新数据时添加long类型的version字段可以保障这一点:如果ES发现此次更新数据携带的version低于目前数据的version则将会拒绝。

curl -H "Content-Type: application/json" -XPOST 'http://es00:9200/your_index/_doc/1001?version=1&version_type=external' -d '
{
    "field": "内容"
}
'

9 对文档进行局部更新

通过使用_update方法即可对文档的部分字段进行局部更新,但是我们要知道,这个局部更新也没有违背”ES中的数据都是只读“的原则,也是进行了如下系列的操作:

  1. 获取要更新的文档
  2. 根据修改请求对其在临时存储中进行修改
  3. 删掉要更新的文档
  4. 重建文档
curl -H "Content-Type: application/json" -XPOST 'http://es00:9200/your_index/_doc/1001/_update' -d '
{
  "doc":{
    "field": "更新内容"
  }
}
'

10 使用脚本更新文档

我们可以使用ES自带的脚本语言Groovy进行文档的更新。

1 新建一个条数据

curl -H "Content-Type: application/json" -XPOST 'http://es00:9200/your_index/_doc/1001' -d '
{
  "tag": ["book", "tool"],
  "count": 100
}
'

2 count + 20

curl -H "Content-Type: application/json" -XPOST 'http://es00:9200/your_index/_doc/1001/_update' -d '
{
  "script" : "ctx._source.count+=20"
}
'

3 upsert
如果担心更新的目标没有对应字段(比如上面的count),可以使用upsert指定默认值。

curl -H "Content-Type: application/json" -XPOST 'http://es00:9200/your_index/_doc/1002/_update' -d '
{
  "script" : "ctx._source.count+=20",
  "upsert": {
    "count": 1 
  }  
}
'

11 更新冲突重试

通过指定retry_on_conflict字段,即可在更新失败时进行自动重试,减少丢数据的风险。

curl -H "Content-Type: application/json" -XPOST 'http://es00:9200/your_index/_doc/1002/_update?retry_on_conflict=5' -d '
{
  "script" : "ctx._source.count+=20",
  "upsert": {
    "count": 1 
  }  
}
'

12 批量获取不同类型的文档数据

当你需要同时获取不同索引的数据时,可以使用mget方法,比如:

curl -H "Content-Type: application/json" -XGET 'http://es00:9200/_mget' -d '
{
  "docs": [
    {
      "_index": "your_index",
      "_id": "cZeQEYIBJnF0z3Du5UvX"
    },
    {
      "_index": "test",
      "_id": "cJd-EYIBJnF0z3DuYUuz"
    }
  ]
}
'

批量执行建议

通常一次请求文档数量在1000-5000个,请求体大概控制在5-15MB。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【ElasticSearch系列连载】7. 关于ES数据读写那点事儿 的相关文章

随机推荐

  • mysql半同步复制安装配置

    一 半同步复制介绍 1 半同步复制产生的起源 默认情况下 MySQL复制是异步的 主服务器将事件写入其二进制日志 但不知道从服务器是否或何时检索并处理它们 对于异步复制 如果主服务器崩溃 它提交的事务可能不会传输到任何从服务器 因此 在这种
  • swing jtextArea滚动条和文字缩放

    当加了滚动条的jtextArea添加滚动事件比如缩放ctrl wheel时 添加的滚动事件和滚动缩放事件会重合 如何让这两个事件同时发生而不会相互干扰呢 也就是滚动条放大缩小时文本不会发生上下滚动 import javax swing im
  • 刷脸支付飞速发展带动了支付技术的变革

    移动支付的飞速发展带动了支付技术的变革 NFC支付 二维码支付 指纹支付等支付方式正活跃在我们的日常生活中 而人脸识别技术的成熟和人们对支付便捷安全性需求的提升 使得刷脸支付逐渐进入大众视野 随着移动支付的飞速发展 聚合支付也迅速渗透到各种
  • Hibernate注解开发关于Id的若干问题

    Hibernate的基本注解注解式开发 Hibernate基本注解 其实在id的注解上 还是有很多有意思的东西 这些东西我们要从Hibernate内置的主键生成策略讲起 Hibernate内置的主键生成策略 一 assigned 主键由外部
  • 【读书笔记->统计学】11-02 总体和样本的估计-总体比例、样本比例、根据总体预测样本比例概念简介

    总体比例与样本比例 假设一个情境 曼帝糖果公司再一次进行了抽样 以便利用调查结果预测 总体中有多大比例的人 可能偏爱曼帝公司的糖球 结果发现 在40个人中有32个人偏爱他们的口香糖球 其余8个人则偏爱竞争对手的口香糖球 首席执行官感兴趣的是
  • 对随机字符串进行排序

    关于对随机字符串进行排序 def createId num salt tp k chars a0v1c2d3e4f5g6h7i8j9k0l1m2n3o4p5q6r7s8t9u0v1w2x4y5z6 生成num个随机数 for n in ra
  • QCustomPlot系列(7)-鼠标跟随显示坐标值(也即:十字游标功能)游标可以吸附采样点

    先来个动图看看效果 这个动图中实现的功能有 1 十字线游标的X值跟随鼠标 Y值不跟随 2 游标的Y值跟随鼠标的X值对应的曲线的Y值 可以点击图例 更换游标跟随哪个曲线的Y值 3 游标不会出现在曲线中不存在点上 而是自动吸附到距离鼠标最近的曲
  • ElasticSearch V2.3部署问题

    ElasticSearch V2 3 CentOS 7 3个节点 研究ElasticSearch V2 3 进行了2天 终于搞明白大部分配置信息含义并且部署成功了 主要问题在于之前的没有接触过 并且2 3版本之前的版本区别不小 根据之前的文
  • 【2023】最新基于Spring Cloud的微服务架构分析

    Spring Cloud是一个相对比较新的微服务框架 2016年才推出1 0的release版本 虽然Spring Cloud时间最短 但是相比Dubbo等RPC框架 Spring Cloud提供的全套的分布式系统解决方案 Spring C
  • 【论文阅读翻译】Action Assessment by Joint Relation Graph

    论文阅读翻译 Action Assessment by Joint Relation Graph KeyWords Abstract Introduction Related Work Approach Experiment KeyWord
  • docker基础篇-----04-----命令添加容器数据卷、dockerfile添加容器数据卷、容器间数据卷共享(--volumes-from)

    参考文章 学习笔记 尚硅谷周阳老师的Docker教程学习笔记 一 容器数据卷 1 容器数据卷 1 什么是容器数据卷 容器删除后数据自然也就没有了 所以用卷来保存数据 容器数据卷功能是持久化和数据共享 卷就是目录或文件 存在于一个或多个容器中
  • springboot中ElasticSearch入门与进阶:组合查询、Aggregation聚合查询(你想要的都有)

    1 springboot中配置elasticSearch 1 1在工程中引入相关的jar包 1 1 1 在build gradle中添加需要的jar包 我创建的gradle工程 对应的maven工程也是一样 添加对应的jar包即可 添加 S
  • linux shell 时间运算以及时间差计算方法

    最近一段时间 在处理Shell 脚本时候 遇到时间的处理问题 时间的加减 以及时间差的计算 1 时间加减 这里处理方法 是将基础的时间转变为时间戳 然后 需要增加或者改变时间 变成 秒 如 1990 01 01 01 01 01 加上 1小
  • 3D人脸模型Flame ----《Learning a model of facial shape and expression from 4D scans》论文讲解及代码注释

    前文 在阅读论文前 首先我们要有一定的知识储备 包括人脸建模 表情制作 旋转转换等 才能方便我们的论文理解 所以首先我会讲解一些关键的知识点 Flame模型的作用 Flame是一个3D人脸的通用模型 举个例子 你现在有一个特定人的3D人脸扫
  • LeetCode练习笔记

    c 解法 文章目录 1 两数之和 简单 题目 方法一 两遍哈希表 方法二 一遍哈希表 2 整数反转 中等 题目 解题方法 3 无重复字符的最长子串 中等 解题方法 4 寻找两个正序数组的中位数 难 解题方法 5 腾讯 6 字节跳动 7 腾讯
  • GCC/CLANG编译器

    文章目录 编译指令 编译过程 预处理 生成汇编代码 词法分析 语法分析 语义分析 生成中间代码 代码生成 LLVM IR 汇编 链接 lib库的链接 clang 编译指令 链接方式 将OC反编译为C GCC是在linux下使用的编译器 Cl
  • Research Productivity Index-概率dp

    题目描述 Angela is a new PhD student and she is nervous about the upcoming paper submission deadline of this year s research
  • 百度又发布一个神器!网友直呼好家伙

    目标检测作为计算机视觉领域的顶梁柱 不仅可以独立完成车辆 商品 缺陷检测等任务 也是人脸识别 视频分析 以图搜图等复合技术的核心模块 在自动驾驶 工业视觉 安防交通等领域的商业价值有目共睹 正因如此 YOLOv5 YOLOX PP YOLO
  • 你了解这些算法吗?SHA256、RIPEMD-160、DES、AES、RSA、ECC

    一 HASH算法 哈希散列算法和哈希摘要算法都叫做哈希算法 1 概念 把一段任意长度的数据变成均匀分布固定长度的数据 反之不可以 Hash不可逆 在任何电脑 手机 或者笔算Hash值都是一样的 y Hash x 已知x可以得到y 反之不可以
  • 【ElasticSearch系列连载】7. 关于ES数据读写那点事儿

    1 对文档建索引 1 1 自定义文档ID 如果数据本身有自己的唯一标记 那么在建立索引时可以使用id来指定文档的id 如下 使用curl在your index索引下写入一个id 1001的文档 curl H Content Type app