ES 索引文档,按_id查找、更新、删除文档

2023-05-16

一、索引(新建)文档

通过使用 index API ,文档可以被 索引 —— 存储和使文档可被搜索。 但是首先,我们要确定文档的位置。正如我们刚刚讨论的,一个文档的 _index_type_id 唯一标识一个文档。

注:
ES7.x版本Type已经移除, _type字段那里变为固定值 _doc!!!

我们可以提供自定义的 _id 值,或者让 index API 自动生成。

1.1、自定义_id

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

把一些文档放到consumer索引中。我们将在consumer索引中索引一个简单的客户文档,其ID为1,如下所示:

PUT /customer/_doc/1?pretty
{
  "name": "John Doe"
}

响应:

{
  "_index" : "customer",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 0,
  "_primary_term" : 1
}

如上,我们可以看到在customer索引中成功地创建了一个新的customer文档。文档还有一个内部ID 1,我们在索引时指定了它。

1.2、自动创建主键

如果你的数据没有自然的 ID, Elasticsearch 可以帮我们自动生成 ID 。 请求的结构调整为: 不再使用 PUT , 而是使用 POST :

POST /customer/_doc/?pretty
{
  "name": "make Doe"
}

响应:

{
  "_index" : "customer",
  "_type" : "_doc",
  "_id" : "YWSApXEBsOGGEpTGJEmD",
  "_version" : 1,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 3,
  "_primary_term" : 1
}

1.3、创建新文档

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

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

POST /website/blog/
{ ... }

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

第一种方法使用 op_type 查询-字符串参数:

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

第二种方法是在 URL 末端使用 /_create :

PUT /website/blog/123/_create
{ ... }
另一方面,如果具有相同的 _index 、 _type 和 _id 的文档已经存在,
Elasticsearch 将会返回 409 Conflict 响应码,以及如下的错误信息:
{
  "error": {
    "root_cause": [
      {
        "type": "version_conflict_engine_exception",
        "reason": "[1]: version conflict, document already exists (current version [3])",
        "index_uuid": "UmtZgqkeTBKFQun4Xs3R1A",
        "shard": "0",
        "index": "customer"
      }
    ],
    "type": "version_conflict_engine_exception",
    "reason": "[1]: version conflict, document already exists (current version [3])",
    "index_uuid": "UmtZgqkeTBKFQun4Xs3R1A",
    "shard": "0",
    "index": "customer"
  },
  "status": 409
}

1.4、返回参数含义

  • id
    Doc的主键,在写入的时候,可以指定该Doc的ID值,如果不指定,则系统自动生成一个唯一的UUID值。
    通过_id值(ES内部转换成_uid)可以唯一在Elasticsearch中确定一个Doc。
    Elasticsearch中,_id只是一个用户级别的虚拟字段,在Elasticsearch中并不会映射到Lucene中,所以也就不会存储该字段的值。
    _id的值可以由_uid解析而来(_uid =type + ‘#’ + id),Elasticsearch中会存储_uid。
  • uid
    _uid的格式是:type + ‘#’ + id。
    _uid会存储在Lucene中,在Lucene中的映射关系如下:dex下可能存在多个id值相同的Doc,而6.0.0之后只支持单Type,同Index下id值是唯一的。
  • _version
    Elasticsearch中每个Doc都会有一个Version,该Version可以由用户指定,也可以由系统自动生成。如果是系统自动生成,那么每次Version都是递增1。
    Elasticsearch 中每个文档都有一个版本号。当每次对文档进行修改时(包括删除), _version 的值会递增。 在 处理冲突 中,我们讨论了怎样使用 _version 号码确保你的应用程序中的一部分修改不会覆盖另一部分所做的修改。
  • _seq_no
    严格递增的顺序号,每个文档一个,Shard级别严格递增,保证后写入的Doc的_seq_no大于先写入的Doc的_seq_no。
    任何类型的写操作,包括index、create、update和Delete,都会生成一个_seq_no。
  • _primary_term
    _primary_term也和_seq_no一样是一个整数,每当Primary Shard发生重新分配时,比如重启,Primary选举等,_primary_term会递增1。
    _primary_term主要是用来恢复数据时处理当多个文档的_seq_no一样时的冲突,避免Primary Shard上的写入被覆盖。

二、按id查询文档

2.1、取回一个文档

GET /customer/_doc/1?pretty

响应:

{
  "_index" : "customer",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 1,
  "_seq_no" : 0,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "name" : "John Doe"
  }
}

除了一个字段之外,这里没有发现任何异常的地方,说明我们找到了一个具有请求的ID 1的文档和另一个字段_source,它返回了我们从上一步索引的完整JSON文档。

如果只想检查一个文档是否存在–根本不想关心内容—​那么用 HEAD 方法来代替 GET 方法。 HEAD 请求没有返回体,只返回一个 HTTP 请求报头:

curl -i -XHEAD http://localhost:9200/website/blog/123

如果文档存在, Elasticsearch 将返回一个 200 ok 的状态码:
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Content-Length: 0

若文档不存在, Elasticsearch 将返回一个 404 Not Found 的状态码:
HTTP/1.1 404 Not Found
Content-Type: text/plain; charset=UTF-8
Content-Length: 0

2.2、取回多个文档

Elasticsearch 的速度已经很快了,但甚至能更快。 将多个请求合并成一个,避免单独处理每个请求花费的网络延时和开销。 如果你需要从 Elasticsearch 检索很多文档,那么使用 multi-get 或者 mget API 来将这些检索请求放在一个请求中,将比逐个文档请求更快地检索到全部文档。

GET /_mget
{
   "docs" : [
      {
         "_index" : "customer",
         "_type" :  "_doc",
         "_id" :    2
      },
      {
         "_index" : "customer",
         "_type" :  "_doc",
         "_id" :    1
      }
   ]
}

响应:

#! Deprecation: [types removal] Specifying types in multi get requests is deprecated.
{
  "docs" : [
    {
      "_index" : "customer",
      "_type" : "_doc",
      "_id" : "2",
      "_version" : 1,
      "_seq_no" : 6,
      "_primary_term" : 1,
      "found" : true,
      "_source" : {
        "name" : "John Doe"
      }
    },
    {
      "_index" : "customer",
      "_type" : "_doc",
      "_id" : "1",
      "found" : false
    }
  ]
}
注意:
提示 弃用:[types removal]不建议在多个get请求中指定types。

如果想检索的数据都在相同的 _index 中(甚至相同的 _type 中),则可以在 URL 中指定默认的 /_index 或者默认的 /_index/_type 。

你仍然可以通过单独请求覆盖这些值:

GET /website/blog/_mget
{
   "docs" : [
      { "_id" : 2 },
      { "_type" : "pageviews", "_id" :   1 }
   ]
}

事实上,如果所有文档的 _index 和 _type 都是相同的,你可以只传一个 ids 数组,而不是整个 docs 数组:

GET /website/blog/_mget
{
   "ids" : [ "2", "1" ]
}

三、更新文档

实际上 Elasticsearch 并不在原有的基础上进行更新。每当我们进行更新时,Elasticsearch 执行步骤如下:

  • 从旧文档构建 JSON
  • 更改该 JSON
  • 删除旧文档
  • 索引一个新文档

3.1、更新全部文档

在 Elasticsearch 中 文档是 不可改变 的,不能修改它们。相反,如果想要更新现有的文档,需要 重建索引 或者进行替换, 我们可以使用相同的 index API 进行实现,在 索引文档 中已经进行了讨论。

PUT /website/_doc/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" :    "_doc",
  "_id" :      "123",
  "_version" : 2,
  "created":   false 
}

3.2、更新部分文档

update 请求最简单的一种形式是接收文档的一部分作为 doc 的参数, 它只是与现有的文档进行合并。对象被合并到一起,覆盖现有的字段,增加新的字段。

#此示例显示如何通过将名称字段更改为“Jane xiang”来更新以前的文档(ID为1):
POST /customer/_update/1?pretty
{
  "doc": { "name": "Jane xiang" }
}

响应:
{
  "_index" : "customer",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 2,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 4,
  "_primary_term" : 1
}
#此示例演示如何通过将名称字段更改为“Jane Doe”来更新以前的文档(ID为1),同时向其添加年龄字段:
POST /customer/_update/1?pretty
{
  "doc": { "name": "Jane Doe", "age": 20 }
}

响应:
{
  "_index" : "customer",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 3,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 5,
  "_primary_term" : 1
}

3.3、使用脚本部分更新文档

脚本可以在 update API中用来改变 _source 的字段内容, 它在更新脚本中称为 ctx._source 。 例如,我们可以使用脚本来增加博客文章中 views 的数量:

POST /website/1/_update
{
   "script" : "ctx._source.views+=1"
}

我们也可以通过使用脚本给 tags 数组添加一个新的标签。在这个例子中,我们指定新的标签作为参数,而不是硬编码到脚本内部。 这使得 Elasticsearch 可以重用这个脚本,而不是每次我们想添加标签时都要对新脚本重新编译:

POST /website/1/_update
{
   "script" : "ctx._source.tags+=new_tag",
   "params" : {
      "new_tag" : "search"
   }
}

获取文档并显示最后两次请求的效果:

{
   "_index":    "website",
   "_type":     "_doc",
   "_id":       "1",
   "_version":  5,
   "found":     true,
   "_source": {
      "title":  "My first blog entry",
      "text":   "Starting to get the hang of this...",
      "tags":  ["testing", "search"], 
      "views":  1 
   }
}

我们甚至可以选择通过设置 ctx.opdelete 来删除基于其内容的文档:

POST /website/1/_update
{
   "script" : "ctx.op = ctx._source.views == count ? 'delete' : 'none'",
    "params" : {
        "count": 1
    }
}

四、删除文档

删除文档的语法和我们所知道的规则相同,只是使用 DELETE 方法:

DELETE /customer/_doc/1

响应:
{
  "_index" : "customer",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 4,
  "result" : "deleted",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 7,
  "_primary_term" : 1
}

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

{
  "_index" : "customer",
  "_type" : "_doc",
  "_id" : "1",
  "_version" : 5,
  "result" : "not_found",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 8,
  "_primary_term" : 1
}

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

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

ES 索引文档,按_id查找、更新、删除文档 的相关文章

  • STM32 DMA +串口 收发数据(不用频繁进入中断) STM32G473 hal库

    1 1 实现方法 利用DMA接收串口数据 xff0c 在一定程度上会节省CPU 的消耗 大多数串口接收都是接收一个字节就中断一次 xff0c 如果串口上需要实时接收大量的数据 xff0c 这就会导致频繁进入中断 xff0c 这样一来 xff
  • tinyalsa 终极详解

    1 tinyalsa 背景 1 tinyalsa位于 Android源码的 external tinyalsa 位置 关于 tinyalsa xff0c tinyalsa是Google在Android 4 0之后推的 基于 alsa内核的用
  • github 出现无法连接成功问题终极详解

    1 fatal unable to access 39 https github com 666zhengyang soft projict set git 39 gnutls handshake failed Error in the p
  • hwclock 和 date 的爱恨情仇终极总结

    nbsp nbsp 里面 的 和 如果是 请参照网上资料 nbsp 命令 获取软件时钟 或者 说是系统时钟 和墙上时钟 开机 重启后 主要用的是 软件时钟 如果 或者异常重启 把这个 软件时间 写到 硬件时钟 nbsp 命令 获取 硬件时钟
  • ubuntu 屏幕缩放调整 终极总结

    1 终端 命令 重置 主题 缩放比例 xff08 手贱把ubutu图标改的很大 xff0c UI显示不出来无法调整 捉鸡 xff09 rm rf config dconf user amp amp reboot 2 xff08 UI 点击设
  • adb push 整个文件夹的内容

    adb push命令的时候 xff0c 有时候需要push某个文件夹下的所有内容到 adb push C xxdir project sdcard xxx
  • 查看某个进程占用空间大小 VmHWM VmRSS终极总结

    cat proc pid status VmPeak 表示进程所占用最大虚拟内存大小 VmSize 表示进程当前虚拟内存大小 VmLck 表示被锁定的内存大小 VmHWM 表示进程所占用物理内存的峰值 VmRSS 表示进程当前占用物理内存的
  • 冯唐成事心法

    刻意练习 动力 43 技巧 43 清晰的目标 魅力值 聊天的框架思维 缺乏目标感 1 状态 感受 2 联想聊天法 3 问对方去聊自己 窗口 信号 她 自己 我们 聊她是为了聊自己 聊自己是 为了聊我们 状态 感受 边聊边感受 1 舒适感 2
  • edge 兼容性问题解决方案

    Edge浏览器出现兼容性问题且所有页面崩溃 xff0c 包括设置均无法打开并访问的解决方法 百度文库
  • 开core信息

    ulimit c unlimited
  • 制定通信协议

    制定通信协议 一 什么是制定通信协议 xff1f 客户端在和服务器进行通信的时候 xff0c 为了让双方都能辨别接收到的消息的内容 xff0c 由发送方和接收方而制定的相关约定 二 为什么制定通信协议 xff1f 在大型的网络游戏中 xff
  • C++ Primer Plus(嵌入式公开课)---1-3章

    1011 C 43 43 Primer Plus 名词解释数值范围 第1章 预备知识1 1 C 43 43 简介1 2 C 43 43 简史1 2 2 C语言编程原理1 2 3 面向对象编程1 2 4 C 43 43 和泛型编程1 2 5
  • Xilinx的Zynq系列,ARM和PL通过DMA通信时如何保证DDR数据的正确性。

    使用ZYNQ或者MPSoC的好处是可以通过PL逻辑设计硬件加速器 xff0c 对功能进行硬件加速 加速器和ARM之间的交互信息一般包含自定义加速指令传递 待计算数据以及计算结果 这三种交互信息为了实现高性能往往需要使用DMA进行通信 考虑两
  • vscode使用clangd开发c++,实现自动补全功能

    安装 在vscode中安装clangd插件 xff0c 如图所示安装插件 xff0c Enable插件clangd xff1b 如果之前安装过C C 43 43 插件的 xff0c 需要将Disable插件C C 43 43 在命令行安装c
  • 串口高波特率下如何稳定接收

    无论是蓝牙 WiFi xff0c 还是4G 5G xff0c 亦或是其它模组 xff0c 都支持AT指令 43 透传模式 AT指令模式下 xff0c 执行查询指令和操作 设置 指令 响应速度快 xff0c 逻辑交互明确 xff0c 不需要复
  • stm32 串口发送多字节数据(结构体版本)

    话不多说先上代码 typedef struct shuju u8 sj0 帧头 u8 sj1 u8 sj2 u8 sj3 u8 sj4 u8 sj5 u8 sj6 u8 sj7 u8 sj8 u8 sj9 帧尾 shuju 实际使用 shu
  • C++ Primer Plus(第六版)读书笔记

    文章目录 C 43 43 Primer Plus xff08 第六版 xff09 第1章 预备知识第2章 开始学习C 43 43 2 1 进入C 43 43 2 2 1 main 指令 2 2 C 43 43 语句2 2 2 赋值语句 第3
  • STM32 (5) 自己写库 构建库函数雏形1 寄存器结构体定义

    前面把基础部分讲得差不多 xff0c 比如说什么是寄存器 xff0c 寄存器映射 xff0c 怎么样来寄存器编程 xff0c 寄存器编程的时候应该参考官方的什么手册 xff0c 前面讲了什么是寄存器 怎么使用寄存器编程 寄存器编程的时候应该
  • 编译器优化对自定义延时程序的影响(volatile详解实验一)

    由此可见 xff08 C语言volatile关键字详解 xff09 xff0c 编译器优化会对自定义延时程序有影响 xff0c 我们深入汇编程序去探讨产生怎样的影响 xff01 首先是未加 volatie 使用和未使用编译器优化汇编程序的对
  • C语言之大小端转换

    include lt stdio h gt unsigned int reverse byte char c char num unsigned int r 61 0 int i for i 61 0 i lt num i 43 43 r

随机推荐

  • 世界坐标系、相机坐标系和图像坐标系的转换

    相机标定笔记 坐标系转换四个不同类型的坐标系1 世界坐标系2 相机坐标系3 图像物理坐标系4 图像像素坐标系 坐标转换世界坐标 相机坐标 xff08 刚性变换 xff09 绕 X X X 旋转
  • 【C++】strpbrk() 字符串检索函数

    strpbrk 字符串检索函数 需要包含头文件 string h xff1b 声明 span class token keyword char span span class token operator span span class t
  • 干货 | 手把手教你搭建一套OpenStack云平台

    1 前言 今天我们为一位朋友搭建一套OpenStack云平台 我们使用Kolla部署stein版本的OpenStack云平台 kolla是用于自动化部署OpenStack的一个项目 xff0c 它基于docker和ansible来实现 xf
  • 完全卸载nginx的详细步骤

    一个执着于技术的公众号 前言 在开局配置Nginx时有可能会配置错误 xff0c 报各种错误代码 看不懂或者懒得去看这个报错时 xff0c 其实最简单的方式是卸载并重装咯 今天就带大家一起学习下 xff0c 如何彻底卸载nginx程序 卸载
  • Windows 11的这19个新功能,你都知道吗?

    参考资料 xff1a https www windowslatest com 2021 10 06 windows 11 new features everything you need to know Windows 11 是 Windo
  • HttpClient 4.3 - 实现HTTP摘要认证(Digest authentication)

    HttpClient 4 实现HTTP摘要认证 HttpClient 4 实现HTTP摘要认证 什么是摘要认证用DefaultHttpClient实现HttpClient 4 3 实现 什么是摘要认证 说到摘要认证 Digest authe
  • 全国DNS服务器IP地址大全、公共DNS大全

    各省公共DNS服务器IP大全 名称各省公共DNS服务器IP大全 114 DNS114 114 114 114114 114 115 115阿里 AliDNS223 5 5 5223 6 6 6百度 BaiduDNS180 76 76 76
  • 如何在CentOS7上禁用或关闭SELinux

    介绍 SELinux 是内置于 Linux 内核中的强制访问控制 MAC 执行器 它限制了可能对系统构成威胁的个别服务的权限 没有 SELinux 的 CentOS 系统依赖于其所有特权软件应用程序的配置 单个错误配置可能会危及整个系统 为
  • 运维常用的 35 个Linux Shell 脚本,一定能帮到你!

    作为一名 Linux 工程师 xff0c 会写好的脚本不仅能提高工作效率 xff0c 还能有更多的时间做自己的事 最近在网上冲浪的时候 xff0c 也注意收集一些大佬写过的脚本 xff0c 汇总整理一下 xff0c 欢迎收藏 xff0c 与
  • 超好用的开源 IP 地址管理系统,告别传统 Excel 统计方式!

    来自 xff1a 释然IT杂谈 一 前言 xff1a 对于运维管理人员 xff0c ip地址进行管理很重要 xff0c 很多公司都是采用电子文档的形式 xff0c 以手工更新为主 xff0c 对ip地址和子网的实际使用情况无法进行有效的实时
  • Linux运维从入门到精通,看这一篇就够了~

    作为一名 Linux 运维工程师 xff0c 总是会有种 书到用时方恨少 的感觉 xff0c 其根本原因还是技能掌握的不够扎实 所以运维朋友一定要多学习 xff0c 提升技能 xff0c 下面分享一份专门针对运维朋友的资料包 xff0c 相
  • K8S CPU 请求和限制,是否有很好的选择?

    Limits 和 Requests 并不是 CPU 管理的灵丹妙药 xff0c 在某些情况下 xff0c 其他替代方案可能是更好的选择 在这篇博文中 xff0c 您将了解到 xff1a CPU requests 如何工作CPU limits
  • 作为一名Linux用户,你得了解这15个工具!

    来源 xff1a 浩道Linux 在普通人眼里 xff0c 使用Linux系统的用户本身已经很有 极客范儿 了 xff0c 但是在技术人员眼中 xff0c 这只是很普通的层级 使用本文推荐的几个Linux系统下的工具 xff0c 能让你瞬间
  • 虚拟网络namespace 到bridge

    前言 容器的网络是一大难点 xff0c 不管是docker 还是kubernetes 都绕不开计算机网络 以下的介绍主要以计算机网络的namespace 和bridge 两个方面来展开介绍 xff0c 方便深入理解容器的网络原理 1 nam
  • 用OpenCV实现目标追踪的八种方法(转)

    原文地址 xff1a http m elecfans com article 722414 html 编者按 xff1a 目标跟踪作为机器学习的一个重要分支 xff0c 加之其在日常生活 军事行动中的广泛应用 xff0c 很多国内外学者都对
  • turbostat超频检测工具

    介绍 turbostat为Intel提供的超频检测工具 xff0c 可以真正在Linux下获取睿频频率的工具 由下可知 xff1a 物理cpu个数为2 xff0c 核心数为14 xff0c 支持超线程 xff0c 逻辑cpu数为56 xff
  • C# HttpClient Digest 摘要认证 Cookie设置

    C HttpClient Digest 摘要认证 Cookie设置 1 创建凭证信息集 2 创建HttpClientHandler 3 创建HttpClient 4 发生请求 span class token comment 创建凭证信息集
  • MongoDB 批量操作(bulkWrite)

    一 概述 mongodb 3 2 版中的新版本提供了db collection bulkWrite 方法提供了执行批量插入 更新和删除操作的能力 mongodb 还支持批量插入 db collection insertMany 1 1 语法
  • Linux动态库的编译与使用(两种方式:链接进可执行程序、动态加载)

    第一步 xff1a 编写Linux程序库 文件1 动态库接口文件 span class token comment 动态库接口文件getmaxlen h span span class token macro property span c
  • ES 索引文档,按_id查找、更新、删除文档

    一 索引 xff08 新建 xff09 文档 通过使用 index API xff0c 文档可以被 索引 存储和使文档可被搜索 但是首先 xff0c 我们要确定文档的位置 正如我们刚刚讨论的 xff0c 一个文档的 index type 和