当前位置: 首页 > 工具软件 > MultiGet > 使用案例 >

Elasticsearch使用MultiGet批量获取文档与使用Bulk批量操作

欧阳嘉年
2023-12-01
Multi Get 批量获取

Multi Get API可以通过索引名、类型名、文档id一次得到一个文档集合,文档可以来自同一个索引库,也可以来自不同的索引库。

GET /_mget
{
  "docs":[
	 {
		"_index": "lib",
		"_type": "user",
		"_id": "1"
	 },
	 {
		"_index": "lib",
		"_type": "user",
		"_id": "2"
	 },
	 {
		"_index": "lib",
		"_type": "user",
		"_id": "3"
	 }
  ]
}

# 可以指定具体的字段
GET /_mget
{
  "docs":[
	 {
		"_index": "lib",
		"_type": "user",
		"_id": "1",
		"_source": "interests"
	 },
	 {
		"_index": "lib",
		"_type": "user",
		"_id": "2",
		"_source": {"age","interests"}
	 }
  ]
}

# 获取同索引同类型下的不同文档
GET /lib/user/_mget
{
  "docs":[
	 {
		"_id": "1"
	 },
	 {
		"_type": "user", # 若是指定索引和类型必须和请求头上的保持一致,否者将会报错。
		"_id": "2"
	 }
  ]
}

# 也可以使用下面这种更为简化的写法
GET /lib/user/_mget
{
  "ids":["1","2"]
}
Bulk 批量操作

bulk的格式:
{action:{metadata}}\n
{requstbody}\n (请求体)

  • action:(行为),包含create(文档不存在时创建)、update(更新文档)、index(创建新文档或替换已用文档)、delete(删除一个文档)。
    create和index的区别:如果数据存在,使用create操作失败,会提示文档已存在,使用index则可以成功执行。
  • metadata:(行为操作的具体索引信息),需要指明数据的_index、_type、_id。

示例:

{"delete":{"_index":"lib","_type":"user","_id":"1"}}

批量添加

POST /lib2/books/_bulk
{"index":{"_id":1}}  # 行为:索引信息
{"title":"Java","price","55"} # 请求体
{"index":{"_id":2}}
{"title":"Html5","price","45"}
{"index":{"_id":3}}
{"title":"Php","price","35"}`
{"index":{"_id":4}}
{"title":"Python","price","50"}

# 返回结果
{
  "took": 60,
  "error": false # 请求是否出错,返回false、具体的错误
  "items": [
	 # 操作过的文档的具体信息
	 {
		"index":{
		   "_index": "lib",
		   "_type": "user",
		   "_id": "1",
		   "_version": 1,
		   "result": "created", # 返回请求结果
		   "_shards": {
			  "total": 1,
			  "successful": 1,
			  "failed": 0
		   },
		   "_seq_no": 0,
		   "_primary_trem": 1
		   "status": 200
	    }
	}, 
	... 
  ]
}

批量删除
删除的批量操作不需要请求体

POST /lib/books/_bulk
{"delete":{"_index":"lib","_type":"books","_id":"4"}} # 删除的批量操作不需要请求体
{"create":{"_index":"tt","_type":"ttt","_id":"100"}}
{"name":"lisi"} # 请求体
{"index":{"_index":"tt","_type":"ttt"}} # 没有指定_id,elasticsearch将会自动生成_id
{"name":"zhaosi"} # 请求体
{"update":{"_index":"lib","_type":"books","_id":"4"}} # 更新动作不能缺失_id,文档不存在更新将会失败
{"doc":{"price":58}} # 请求体

bluk一次最大处理多少数据量
bulk会将要处理的数据载入内存中,所以数据量是有限的,最佳的数据两不是一个确定的数据,它取决于你的硬件,你的文档大小以及复杂性,你的索引以及搜索的负载。

一般建议是1000-5000个文档,大小建议是5-15MB,默认不能超过100M,可以在es的配置文件(即$ES_HOME下的config下的elasticsearch.yml)中,bulk的线程池配置是内核数+1。

bulk批量操作的json格式解析
bulk的格式:
{action:{metadata}}\n
{requstbody}\n (请求体)

  1. 不用将其转换为json对象,直接按照换行符切割json,内存中不需要json文本的拷贝。
  2. 对每两个一组的json,读取meta,进行document路由。
  3. 直接将对应的json发送到node上。

为什么不使用如下格式:

[{"action":{},"data":{}}]

这种方式可读性好,但是内部处理就麻烦;耗费更多内存,增加java虚拟机开销:

  1. 将json数组解析为JSONArray对象,在内存中就需要有一份json文本的拷贝,宁外好友一个JSONArray对象。
  2. 解析json数组里的每个json,对每个请求中的document进行路由。
  3. 为路由到同一个shard上的多个请求,创建一个请求数组。
  4. 将这个请求数组序列化。
 类似资料: