学好Elasticsearch系列-索引的批量操作

bytebuilder
• 阅读 237

本文已收录至 Github,推荐阅读 👉 Java 随想录
微信公众号:Java 随想录

先看后赞,养成习惯。
点赞收藏,人生辉煌。

学好Elasticsearch系列-索引的批量操作

Elasticsearch 提供了_mget和_bulk API 来执行批量操作,它允许你在单个 HTTP 请求中进行多个索引获取/删除/更新/创建操作。这种方法比发送大量的单个请求更有效率。

基于 mget 的批量查询

mget(多文档获取)是 Elasticsearch 中提供的一个 API,用于一次性从同一个索引或者不同索引中检索多个文档。

例子一:

以下是一个 Elasticsearch 的mget(多文档获取)操作示例。在这个示例中,我们将获取索引 test-index 中具有特定 ID 的多个文档。

GET /test-index/_mget
{
  "ids": ["1", "2"]
}

在上述请求中,我们正在获取 ID 为 "1" 和 "2" 的文档。

例子二:

你也可以在不同的索引中获取文档,只需指定每个文档的 _index_id

GET /_mget
{
  "docs": [
    {
      "_index": "test-index",
      "_id": "1"
    },
    {
      "_index": "another-index",
      "_id": "2"
    }
  ]
}

在这个请求中,我们从 "test-index" 索引获取 ID 为 "1" 的文档,并从 "another-index" 索引获取 ID 为 "2" 的文档。

例子三:

在以下的 Elasticsearch mget(多文档获取)例子中,我们将从两个不同的索引获取文档,并且只返回特定的字段:

GET /_mget
{
  "docs": [
    {
      "_index": "test-index-1",
      "_id": "1",
      "_source": ["field1", "field2"]
    },
    {
      "_index": "test-index-2",
      "_id": "2",
      "_source": "field3"
    }
  ]
}

在这个请求中,我们从 "test-index-1" 索引获取 ID 为 "1" 的文档,并只返回 "field1" 和 "field2" 字段。同时,我们从 "test-index-2" 索引获取 ID 为 "2" 的文档,并只返回 "field3" 字段。

源过滤 (_source) 可以用来限制返回的字段。你可以提供一个字段的列表,或者一个单独的字段。注意,如果你请求的字段不存在,它将不会出现在响应中。

基于 bulk 的批量增删改

bulk 基本格式如下:

POST /<index>/_bulk
{"action": {"metadata"}}
{"data"}

bulk api 对 json 的语法有严格的要求,除了 delete 外,每一个操作都要两个 json 串(metadata 和 business data),且每个 json 串内不能换行,非同一个 json 串必须换行,否则会报错。

bulk 操作中,任意一个操作失败,是不会影响其他的操作的,但是在返回结果里,会告诉你异常日志。

增加

POST /_bulk
{ "create" : { "_index" : "product2", "_id" : "2" } }
{ "field1" : "value1", "field2" : "value2" }

在这个请求中,我们创建了一个新的文档,其在 "product2" 索引中的 ID 为 "2",并且包含两个字段 "field1" 和 "field2"。

请注意,这个操作都由两行组成:第一行包含操作类型(在这个示例中为 "create")和元数据;第二行包含要创建或索引的实际文档数据。

删除

删除文档,ES 对文档的删除是懒删除机制,即标记删除(lazy delete 原理)。

POST /_bulk
{ "delete" : { "_index" : "test-index", "_id" : "1" } }
{ "delete" : { "_index" : "test-index", "_id" : "2" } }

在这个请求中,我们从 "test-index" 索引中删除了 ID 为 "1" 和 "2" 的两个文档。

注意,每个 delete 操作仅由一行组成,这一行包含操作类型(在这个示例中为 "delete")以及元数据。

修改

POST /_bulk
{ "update" : { "_index" : "test-index", "_id" : "1" } }
{ "doc" : { "field1" : "new_value1", "field2" : "new_value2" }}
{ "update" : { "_index" : "test-index", "_id" : "2" } }
{ "doc" : { "field1" : "new_value3", "field2" : "new_value4" }}

在这个请求中,我们在 "test-index" 索引中更新了两个文档:

  • 我们更新了 ID 为 "1" 的文档,设置 "field1" 和 "field2" 字段的值为 "new_value1" 和 "new_value2"。
  • 我们也更新了 ID 为 "2" 的文档,设置 "field1" 和 "field2" 字段的值为 "new_value3" 和 "new_value4"。

filter_path

在 Elasticsearch 中,filter_path参数用于过滤返回的响应内容,可以用于减小 Elasticsearch 返回的数据量。当你指明一个或多个路径时,返回的 JSON 对象就只会包含这些路径下的键,它接收一个逗号分隔的列表,其中包含了你想要返回的 JSON 对象内的路径。这个参数支持通配符(*)匹配和数组元素([])匹配。列如:

POST /_bulk?filter_path=items.*.error

上述请求中的 filter_path=items.*.error 会让 Elasticsearch 仅返回 _bulk API 调用结果中的错误信息。items.*.error 这个路径表示,在返回的响应中,匹配到所有存在 error 字段的 items

这样做有两个主要好处:

  1. 它可以提升 Elasticsearch 的性能,因为少量的数据意味着更快的序列化和反序列化。
  2. 它可帮助你聚焦于感兴趣的部分,不必处理无关的数据。

请注意,* 是通配符,代表任何值。

以下是一些其他 filter_path 的示例:

  1. filter_path=took: 这个请求仅返回执行请求所花费的时间(以毫秒为单位)。
  2. filter_path=items._id,items._index: 这个请求仅返回每个 item 的 _id_index 字段。
  3. filter_path=items.*.error: 这个请求会返回所有包含 error 字段的 items。
  4. filter_path=hits.hits._source: 这个请求仅返回搜索结果中的原始文档内容。
  5. filter_path=_shards, hits.total: 这个请求返回关于 shards 的信息和命中的总数。
  6. filter_path=aggregations.*.value: 这个请求仅返回每个聚合的值。

请注意,如果你在 filter_path 中指定了多个字段,你需要使用逗号将它们分隔开。


本篇文章就到这里,感谢阅读,如果本篇博客有任何错误和建议,欢迎给我留言指正。

有收获?希望老铁来个三连,给更多的同学看到这篇文章,顺便激励下我,嘻嘻。

学好Elasticsearch系列-索引的批量操作

老铁们,关注我的微信公众号「Java 随想录」,专注分享技术,文章持续更新,可以关注公众号第一时间阅读。

一个人走的很快,一群人走的更远。关注我,我们一起学习成长!

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
3年前
VBox 启动虚拟机失败
在Vbox(5.0.8版本)启动Ubuntu的虚拟机时,遇到错误信息:NtCreateFile(\\Device\\VBoxDrvStub)failed:0xc000000034STATUS\_OBJECT\_NAME\_NOT\_FOUND(0retries) (rc101)Makesurethekern
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Wesley13 Wesley13
3年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表:时辰时间24时制子时深夜11:00凌晨01:0023:0001:00丑时上午01:00上午03:0001:0003:00寅时上午03:00上午0
Stella981 Stella981
3年前
Linux日志安全分析技巧
0x00前言我正在整理一个项目,收集和汇总了一些应急响应案例(不断更新中)。GitHub地址:https://github.com/Bypass007/EmergencyResponseNotes本文主要介绍Linux日志分析的技巧,更多详细信息请访问Github地址,欢迎Star。0x01日志简介Lin
Stella981 Stella981
3年前
ELK学习笔记之ElasticSearch的索引详解
0x00ElasticSearch的索引和MySQL的索引方式对比Elasticsearch是通过Lucene的倒排索引技术实现比关系型数据库更快的过滤。特别是它对多条件的过滤支持非常好,比如年龄在18和30之间,性别为女性这样的组合查询。倒排索引很多地方都有介绍,但是其比关系型