伸缩自如的ElasticSearch——文档CRUD操作

2023-11-13

文档

在大多数应用中,多数实体或对象可以被序列化为包含键值对的 JSON 对象。 一个 键 可以是一个字段或字段的名称,一个 值 可以是一个字符串,一个数字,一个布尔值, 另一个对象,一些数组值,或一些其它特殊类型诸如表示日期的字符串,或代表一个地理位置的对象:

{
    "name":         "John Smith",
    "age":          42,
    "confirmed":    true,
    "join_date":    "2014-06-01",
    "home": {
        "lat":      51.5,
        "lon":      0.1
    },
    "accounts": [
        {
            "type": "facebook",
            "id":   "johnsmith"
        },
        {
            "type": "twitter",
            "id":   "johnsmith"
        }
    ]
}

通常情况下,我们使用的术语 对象 和 文档 是可以互相替换的。不过,有一个区别: 一个对象仅仅是类似于 hash 、 hashmap 、字典或者关联数组的 JSON 对象,对象中也可以嵌套其他的对象。 对象可能包含了另外一些对象。在 Elasticsearch 中,术语 文档 有着特定的含义。它是指最顶层或者根对象, 这个根对象被序列化成 JSON 并存储到 Elasticsearch 中,指定了唯一 ID。

文档元数据

一个文档不仅仅包含它的数据 ,也包含 元数据 —— 有关 文档的信息。 三个必须的元数据元素如下:

  • _index
    文档在哪存放
  • _type
    文档表示的对象类别
  • _id
    文档唯一标识

举个例子就很好理解:

PUT /{index}/{type}/{id}
{
  "field": "value",
  ...
}

如果我们的索引称为 website ,类型称为 blog ,并且选择 123 作为 ID ,那么索引请求应该是下面这样:

PUT /website/blog/123
{
  "title": "My first blog entry",
  "text":  "Just trying this out...",
  "date":  "2014/01/01"
}

如果你的数据没有自然的 ID, Elasticsearch 可以帮我们自动生成 ID 。 请求的结构调整为: 不再使用 PUT 谓词(“使用这个 URL 存储这个文档”), 而是使用 POST 谓词(“存储文档在这个 URL 命名空间下”)。

POST /website/blog/
{
  "title": "My second blog entry",
  "text":  "Still trying this out...",
  "date":  "2014/01/01"
}

GET /website/blog/_seach

{
   "_index":    "website",
   "_type":     "blog",
   "_id":       "AVFgSgVHUP18jI2wRx0w",
   "_version":  1,
   "created":   true
}

自动生成的 ID 是 URL-safe、 基于 Base64 编码且长度为20个字符的 GUID 字符串。 这些 GUID 字符串由可修改的 FlakeID 模式生成,这种模式允许多个节点并行生成唯一 ID ,且互相之间的冲突概率几乎为零。

_index

一个 索引 应该是因共同的特性被分组到一起的文档集合。 例如,你可能存储所有的产品在索引 products 中,而存储所有销售的交易到索引 sales 中。

_type

数据可能在索引中只是松散的组合在一起,但是通常明确定义一些数据中的子分区是很有用的。 例如,所有的产品都放在一个索引中,但是你有许多不同的产品类别,比如 “electronics” 、 “kitchen” 和 “lawn-care”。

这些文档共享一种相同的(或非常相似)的模式:他们有一个标题、描述、产品代码和价格。他们只是正好属于“产品”下的一些子类。

Elasticsearch 公开了一个称为 types (类型)的特性,它允许您在索引中对数据进行逻辑分区。不同 types 的文档可能有不同的字段,但最好能够非常相似。

_id

ID 是一个字符串, 当它和 _index 以及 _type 组合就可以唯一确定 Elasticsearch 中的一个文档。 当你创建一个新的文档,要么提供自己的 _id ,要么让 Elasticsearch 帮你生成。

取文档

在请求的查询串参数中加上 pretty 参数, 正如前面的例子中看到的,这将会调用 Elasticsearch 的 pretty-print 功能,该功能 使得 JSON 响应体更加可读。但是, _source 字段不能被格式化打印出来。相反,我们得到的 _source 字段中的 JSON 串,刚好是和我们传给它的一样。

GET /website/blog/123?pretty
响应体包括目前已经熟悉了的元数据元素,再加上 _source 字段,这个字段包含我们索引数据时发送给 Elasticsearch 的原始 JSON 文档:

{
  "_index" :   "website",
  "_type" :    "blog",
  "_id" :      "123",
  "_version" : 1,
  "found" :    true,
  "_source" :  {
      "title": "My first blog entry",
      "text":  "Just trying this out...",
      "date":  "2014/01/01"
  }
}

GET 请求的响应体包括 {“found”: true} ,这证实了文档已经被找到。 如果我们请求一个不存在的文档,我们仍旧会得到一个 JSON 响应体,但是 found 将会是 false 。 此外, HTTP 响应码将会是 404 Not Found ,而不是 200 OK 。

默认情况下, GET 请求 会返回整个文档,这个文档正如存储在 _source 字段中的一样。但是也许你只对其中的 title 字段感兴趣。单个字段能用 _source 参数请求得到,多个字段也能使用逗号分隔的列表来指定。
GET /website/blog/123?_source=title,text
该 _source 字段现在包含的只是我们请求的那些字段,并且已经将 date 字段过滤掉了。

{
  "_index" :   "website",
  "_type" :    "blog",
  "_id" :      "123",
  "_version" : 1,
  "found" :   true,
  "_source" : {
      "title": "My first blog entry" ,
      "text":  "Just trying this out..."
  }
}

或者,如果你只想得到 _source 字段,不需要任何元数据,你能使用 _source 端点:GET /website/blog/123/_source

{
   "title": "My first blog entry",
   "text":  "Just trying this out...",
   "date":  "2014/01/01"
}

更新文档

在 Elasticsearch 中文档是 不可改变 的,不能修改它们。 相反,如果想要更新现有的文档,需要 重建索引 或者进行替换。

PUT /website/blog/123
{
  "title": "My first blog entry",
  "text":  "I am starting to get the hang of this...",
  "date":  "2014/01/02"
}

在响应体中,我们能看到 Elasticsearch 已经增加了 _version 字段值:

{
  "_index" :   "website",
  "_type" :    "blog",
  "_id" :      "123",
  "_version" : 2,
  "created":   false 
}

created 标志设置成 false ,是因为相同的索引、类型和 ID 的文档已经存在。

在内部,Elasticsearch 已将旧文档标记为已删除,并增加一个全新的文档。 尽管你不能再对旧版本的文档进行访问,但它并不会立即消失。当继续索引更多的数据,Elasticsearch 会在后台清理这些已删除文档。

我们再次用GET方法查询的时候,会发现,这个POST提交的是覆盖了原来的数据的,如果我们不希望全部覆盖,而是像更新一部分数据,应该使用下面的部分更新语句。

POST /website/blog/1/_update
{
   "doc" : {
      "tags" : [ "testing" ],
      "views": 0
   }
}

创建文档

当我们索引一个文档, 怎么确认我们正在创建一个完全新的文档,而不是覆盖现有的呢?

请记住, _index 、 _type 和 _id 的组合可以唯一标识一个文档。所以,确保创建一个新文档的最简单办法是,使用索引请求的 POST 形式让 Elasticsearch 自动生成唯一 _id :

POST /website/blog/
{ ... }

然而,如果已经有自己的 _id ,那么我们必须告诉 Elasticsearch ,只有在相同的 _index 、 _type 和 _id 不存在时才接受我们的索引请求。这里有两种方式,他们做的实际是相同的事情。使用哪种,取决于哪种使用起来更方便。

PUT /website/blog/123/_create
{ ... }
或者
PUT /website/blog/123?op_type=create
{ ... }

如果创建新文档的请求成功执行,Elasticsearch 会返回元数据和一个 201 Created 的 HTTP 响应码。

另一方面,如果具有相同的 _index 、 _type 和 _id 的文档已经存在,Elasticsearch 将会返回 409 Conflict 响应码。

删除文档

DELETE /website/blog/123
如果找到该文档,Elasticsearch 将要返回一个 200 ok 的 HTTP 响应码,和一个类似以下结构的响应体。注意,字段 _version 值已经增加:

{
  "found" :    true,
  "_index" :   "website",
  "_type" :    "blog",
  "_id" :      "123",
  "_version" : 3
}

如果文档没有 找到,我们将得到 404 Not Found 的响应码和类似这样的响应体:

{
  "found" :    false,
  "_index" :   "website",
  "_type" :    "blog",
  "_id" :      "123",
  "_version" : 4
}

即使文档不存在( Found 是 false ), _version 值仍然会增加。这是 Elasticsearch 内部记录本的一部分,用来确保这些改变在跨多节点时以正确的顺序执行。

处理冲突

当我们使用 index API 更新文档 ,可以一次性读取原始文档,做我们的修改,然后重新索引 整个文档 。 最近的索引请求将获胜:无论最后哪一个文档被索引,都将被唯一存储在 Elasticsearch 中。如果其他人同时更改这个文档,他们的更改将丢失

很多时候这是没有问题的。也许我们的主数据存储是一个关系型数据库,我们只是将数据复制到 Elasticsearch 中并使其可被搜索。但有时丢失了一个变更就是 非常严重的 。

在数据库领域中,有两种方法通常被用来确保并发更新时变更不会丢失:

  • 悲观并发控制
    这种方法被关系型数据库广泛使用,它假定有变更冲突可能发生,因此阻塞访问资源以防止冲突。 一个典型的例子是读取一行数据之前先将其锁住,确保只有放置锁的线程能够对这行数据进行修改。
  • 乐观并发控制
    Elasticsearch 中使用的这种方法假定冲突是不可能发生的,并且不会阻塞正在尝试的操作。 然而,如果源数据在读写当中被修改,更新将会失败。应用程序接下来将决定该如何解决冲突。 例如,可以重试更新、使用新的数据、或者将相关情况报告给用户。

Elasticsearch 是分布式的。当文档创建、更新或删除时, 新版本的文档必须复制到集群中的其他节点。Elasticsearch 也是异步和并发的,这意味着这些复制请求被并行发送,并且到达目的地时也许 顺序是乱的 。 Elasticsearch 需要一种方法确保文档的旧版本不会覆盖新的版本

当我们之前讨论 index , GET 和 delete 请求时,我们指出每个文档都有一个 _version (版本)号,当文档被修改时版本号递增。 Elasticsearch 使用这个 _version 号来确保变更以正确顺序得到执行。如果旧版本的文档在新版本之后到达,它可以被简单的忽略。

在更新的时候,可以这样使用语句:

PUT /website/blog/1?version=3&version_type=external
{
  "title": "My first blog entry",
  "text":  "Starting to get the hang of this..."
}

如果冲突,则会报错:

{
  "error": {
    "root_cause": [
      {
        "type": "version_conflict_engine_exception",
        "reason": "[1]: version conflict, current version [4] is higher or equal to the one provided [3]",
        "index_uuid": "8p9Ov8g5QJqCBHM4CUq8wg",
        "shard": "0",
        "index": "blogs"
      }
    ],
    "type": "version_conflict_engine_exception",
    "reason": "[1]: version conflict, current version [4] is higher or equal to the one provided [3]",
    "index_uuid": "8p9Ov8g5QJqCBHM4CUq8wg",
    "shard": "0",
    "index": "blogs"
  },
  "status": 409
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

伸缩自如的ElasticSearch——文档CRUD操作 的相关文章

  • Redis——初识Redis

    Redis简介 Redis的数据结构致力于帮助用户解决问题 而不是像关系型数据库那样 要求用户扭曲问题来适应数据库 除此之外 通过复制 持久化和客户端分片 client side sharding 等特性 用户可以很方便的将Redis扩展成
  • k8s-多节点部署efk-dial tcp 172.20.2.134:5601: getsockopt: connection refused

    异常信息 Error dial tcp 172 20 0 145 5601 getsockopt connection refused Trying to reach http 172 20 0 145 5601 分析 部署好efk后 通过
  • Azkaban的囚徒——Azkaban运行模式和流

    文章目录 Azkaban运行模式 Azkaban运行 Azkaban 流 Job Dependency Azkaban运行模式 在3 x版本里 提供了3种运行模式 the stand alone solo server mode stand
  • Dubbo——快速启动(2)

    快速启动 Dubbo 采用全 Spring 配置方式 透明化接入应用 对应用没有任何 API 侵入 只需用 Spring 加载 Dubbo 的配置即可 Dubbo 基于 Spring 的 Schema 扩展 进行加载 mvn
  • Distributed Database System —— Multi-raft协议介绍

    文章目录 Multi Raft协议 Multi Raft需要解决的问题 Multi Raft实现细节 Cockroach Multi Raft Raft Consistency of Range Replicas Range Leaders
  • Dubbo——Dubbo初识(1)

    背景 随着互联网的发展 网站应用的规模不断扩大 常规的垂直应用架构已无法应对 分布式服务架构以及流动计算架构势在必行 亟需一个治理系统确保架构有条不紊的演进 单一应用架构 当网站流量很小时 只需一个应用 将所有功能都部署在一起 以减少部署节
  • windows安装docker desktop

    windows安装docker desktop 前言 一 docker desktop 是什么 二 安装步骤 1 下载 2 安装 总结 前言 这里针对windows 10 家庭中文版 其他版本部分步骤可跳过 一 docker desktop
  • Hadoop是小象——YARN / Split&Block

    了解Hadoop架构 Hadoop可运行于一般的商用服务器上 具有高容错 高可靠性 高扩展性等特点 特别适合写一次 读多次的场景 其架构如下 HDFS 分布式文件存储 可靠性由心跳机制和冗余提供 YARN 分布式资源管理 MapReduce
  • MQ相关问题

    ActiveMQ 功能完善 性能相对差 社区文档很久不更新了 丢失可能低 万级QBS 毫秒延迟 主从高可用 RabbitMQ 基于erlang 扩展性差 社区活跃 中小企业用 万级QBS 微妙延迟 主从高可用 RocketMQ 阿里开源 定
  • JavaEE架构之传统三层架构,集群架构,分布式架构,微服务架构

    javaEE架构 1 传统三层架构 all in one项目 传统三层架构大致可以分为表现层 业务层和持久层 数据访问层 其中表现层负责接受请求和转发请求 业务层负责处理请求 注 事务管理 日志记录等AOP类型的操作均封装在这一层 持久层主
  • Hadoop是小象——Hadoop集群安装配置

    文章目录 所需软件 集群网络配置 集群SSH免密登陆设置 Hadoop安装配置 所需软件 Linux所需软件包括 JavaTM1 5 x 必须安装 建议选择Sun公司发行的Java版本 以前安装过 ssh 必须安装并且保证 sshd一直运行
  • Springcloud五大组件

    1 什么是springcloud springcloud是一系列框架的有序集合 它利用springboot的开发便利性巧妙地简化了分布式系统基础设施的开发 如服务发现注册 配置中心 消息总线 负载均衡 断路器 数据监控等 都可以用sprin
  • Apache架构师都遵循的30条设计原则

    Srinath 通过不懈的努力最终总结出了 30 条架构原则 他主张架构师的角色应该由开发团队本身去扮演 而不是专门有个架构师团队或部门 Srinath 认为架构师应该扮演的角色是一个引导者 讨论发起者 花草修建者 而不是定义者和构建者 S
  • 几张架构图阐述微服务架构治理相关知识点

    微服务架构的技术点 超时时间设置 接口重试机制 流量QPS限流 请求熔断处理 请求降级处理 今天给大家分享一下以上相关的知识点 通过微服务系统之间RPC通信的方式 以架构图的形式给大家展开介绍 1 超时时间设置 应用访问业务系统A 业务系统
  • 伸缩自如的ElasticSearch——文档CRUD操作

    文章目录 文档 文档元数据 index type id 取文档 更新文档 创建文档 删除文档 处理冲突 文档 在大多数应用中 多数实体或对象可以被序列化为包含键值对的 JSON 对象 一个 键 可以是一个字段或字段的名称 一个 值 可以是一
  • Zookeeper——zookeeper基础

    在深入了解ZooKeeper的运作之前 让我们来看看ZooKeeper的基本概念 我们将在本章中讨论以下主题 Architecture 架构 Hierarchical namespace 层次命名空间 Session 会话 Watches
  • Elasticsearch使用教程

    下载ES elasticsearch的下载地址 https www elastic co cn downloads elasticsearch ik分词器的下载地址 https github com medcl elasticsearch
  • 应用使用Druid连接池经常性断链问题分析

    前段时间有应用使用Druid连接池经常的提示断链报错 整个问题排查分析过程很有意思 这里将Druid连接池 数据库层以及负载均衡层的配置分析下 记录整个问题的分析过程 同时梳理下Druid连接池的配置和连接保活及回收机制 1 问题背景 应用
  • Distributed System Transaction —— 2PL

    文章目录 2PL 并发控制常见的方式有2PL MVCC等方式 2PL 两阶段锁 two phase locking 是用来解决多线程之间的竞态条件的 其算法非常简单 数据库中的每一个数据对象都有两种锁 S hared lock 和 e X
  • 什么是分布式架构

    一 分布式架构定义 什么是分布式架构 分布式系统 distributed system 是建立在网络之上的软件系统 内聚性 是指每一个数据库分布节点高度自治 有本地的数据库管理系统 透明性 是指每一个数据库分布节点对用户的应用来说都是透明的

随机推荐

  • 多维时序

    多维时序 MATLAB实现SCNGO CNN Attention多变量时间序列预测 目录 多维时序 MATLAB实现SCNGO CNN Attention多变量时间序列预测 预测效果 基本介绍 程序设计 参考资料 预测效果 基本介绍 1 S
  • Pretues和Keil使用stm32F103C6芯片实现跑马灯

    一 Protues创建工程 添加好名称 不断下一步就行 二 pretues添加原件 构建电路图 二 keil做代码 添加文件这里不做说明 注意一下几个点 1 芯片使用stm32F103c6 2 mdk的汇编文件随之改变 3 宏定义改成stm
  • 【NLP】使用 LSTM 和Beam Search进行文本自动完成

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • 获取腾讯视频的视频url

    爬视频喽 1 获取链接地址 如下图 类似 https v qq com x page q0900ebm4qz html 2 取值 取上图获取到的加粗的数据 然后替换下面链接中的加粗数据http vv video qq com getinfo
  • 记一次python3 pip 报错Retrying

    错误信息如下 Retrying Retry total 4 connect None read None redirect None status None after connection broken by SSLError Can t
  • Nginx超详细入门教程

    目录 一 nginx配置文件介绍 二 nginx的核心功能 1 反向代理 lt 1 gt 正向代理 lt 2 gt 反向代理 lt 3 gt 准备工作 2 负载均衡 3 负载均衡策略 4 动静分离 三 Nginx的高可用性 1 准备两台虚拟
  • Qt控件使用方法技巧合集

    Qt控件使用方法技巧合集 本篇博客代码示例包含C 版本和Python版本 不管是哪个版本 Qt的API都是一样的 使用方式大同小异 文章目录 Qt控件使用方法技巧合集 1 QTextEdit设置背景色和文本颜色 2 QMessageBox的
  • GBK转成utf-8,java实现及讲解,androidstudio学习

    好吧 看来问的人和回答的人都不一定清楚什么是 编码和编码格式 以及如何理解 java中字符串的编码 首先明确几点 unicode是一种 编码 所谓编码就是一个编号 数字 到字符的一种映射关系 就仅仅是一种一对一的映射而已 可以理解成一个很大
  • 连接SqlServer数据库报错version TLS10 is not accepted by client preferences [TLS12,TLS13]

    报错内容 我的报错信息如下 其他类似的可能也好使 你们可以试试 The server selected protocol version TLS10 is not accepted by client preferences TLS12 T
  • 程序员进阶攻略-笔记-021~030

    信息 过载与有效 忙碌 充实而疲倦 的虚幻假象 在这个信息过载的洪流中 需要的就是在这股洪流中筛选信息并建立自己中流砥柱般的 知识磐石 心智 这两个字合在一起是一个意思 分开为 心 和 智 两个字又可以分别解释为 心 是你对需要的选择 从心
  • 八款国产操作系统

    点击上方蓝字 快速关注 目前世界上存在的那些操作系统 Windows MAC OS X MVX DOS VSE UNIX Linux等 很少见到国产操作系统的影子 你知道国产操作系统有那些吗 虽然国内的操作系统我们可能用不上 但我们有足够的
  • sd卡详细资料

    1 简介 SD卡是基于flash的存储卡 SD卡和MMC卡的区别在于初始化过程不同 SD卡的通信协议包括SD总线和SPI两类 SD卡使用卡内智能控制模块进行FLASH操作控制 包括协议 安全算法 数据存取 ECC算法 缺陷处理和分析 电源管
  • Nginx hls流媒体服务器实现直播

    通过Nginx模块nginx rtmp module实现hls流媒体服务器并用OBS进行推流 一 直播协议简介 首先 在搭建服务之前先了解下目前主流的几个直播协议 1 RTMP 实时消息传输协议 Real Time Messaging Pr
  • ERROR:root:Internal Python error in the inspect module.

    Google Colab运行终端命令报错 python xxxxx ERROR root Internal Python error in the inspect module Below is the traceback from thi
  • 维修汽车服务器,修车别被坑,老司机2分钟告诉你,修理厂和4S店之间不为人知的秘密!...

    在修车行业的新闻太多了 也有报道过一辆车坏了一颗螺丝修了几千上万块的新闻并不少见 对于修车多数人的第一反应就是 修车行业太坑了 尤其是私人修理厂 品牌修理店和4S店还稍微好点 但是事实真的是这样吗 首先让我们先了解一下现在的修理行业 现在开
  • 空间战场态势感知系统

    兵工科技 杂志就数字冰雹的 空间战场态势感知指挥可视化系统 对市场总监丁冬先生进行了专访报道 现代战争强调C4ISR技术 指挥中心在千里万里之外 要通过信息化技术对整个海 陆 空 天 电磁战场进行全面的了解 掌握和指挥控制 那么传统指挥部里
  • css在高度为百分比时候的文字垂直居中方法

    对于高度单位是px的div 想让文字垂直居中很简单 line height height就可以了 但是对于高度为百分比的div 如何让文字垂直居中呢 方法一 给需要垂直居中的文字增加一个父元素 给父元素设置 display table 给需
  • Unity3D 万向锁问题

    Unity3D 万向锁问题 1 问题 描述 在 unity3D中 对欧拉角的旋转顺序为Y X Z 那么我们可以通过一个Cube来直观看到这种现象 创建一个Cube 我们只要按照 Y X Z顺序 操作Cubu的Transform属性面板的欧拉
  • 启动gazebo时,[Err] [REST.cc:205] Error in REST request

    启动gazebo时 Err REST cc 205 Error in REST request 1 gazebo在安装ROS的时候就已经安装了 使用以下命令可检查是否安装成功 roslaunch gazebo ros empty world
  • 伸缩自如的ElasticSearch——文档CRUD操作

    文章目录 文档 文档元数据 index type id 取文档 更新文档 创建文档 删除文档 处理冲突 文档 在大多数应用中 多数实体或对象可以被序列化为包含键值对的 JSON 对象 一个 键 可以是一个字段或字段的名称 一个 值 可以是一