本文已收录至 Github,推荐阅读 👉 Java 随想录
先看后赞,养成习惯。
点赞收藏,人生辉煌。
文章目录
- 基于 mget 的批量查询
- 基于 bulk 的批量增删改
- 增加
- 删除
- 修改
- filter_path
Elasticsearch 提供了 _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
。
这样做有两个主要好处:
- 它可以提升 Elasticsearch 的性能,因为少量的数据意味着更快的序列化和反序列化。
- 它可帮助你聚焦于感兴趣的部分,不必处理无关的数据。
请注意,*
是通配符,代表任何值。
以下是一些其他 filter_path
的示例:
filter_path=took
: 这个请求仅返回执行请求所花费的时间(以毫秒为单位)。filter_path=items._id,items._index
: 这个请求仅返回每个 item 的_id
和_index
字段。filter_path=items.*.error
: 这个请求会返回所有包含error
字段的 items。filter_path=hits.hits._source
: 这个请求仅返回搜索结果中的原始文档内容。filter_path=_shards, hits.total
: 这个请求返回关于shards
的信息和命中的总数。filter_path=aggregations.*.value
: 这个请求仅返回每个聚合的值。
请注意,如果你在 filter_path
中指定了多个字段,你需要使用逗号将它们分隔开。
本篇文章就到这里,感谢阅读,如果本篇博客有任何错误和建议,欢迎给我留言指正。
有收获?希望老铁来个三连,给更多的同学看到这篇文章,顺便激励下我,嘻嘻。
老铁们,关注我的微信公众号「Java 随想录」,专注分享技术,文章持续更新,可以关注公众号第一时间阅读。
一个人走的很快,一群人走的更远。关注我,我们一起学习成长!