elasticsearch使用bulk实现批量操作
1、批量查询
Multi Get 批量获取
Multi Get API可以通过索引名、类型名、文档id一次得到一个文档集合,文档可以来自同一个索引库,也可以来自不同的索引库。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | 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 批量操作
(1) 比如,我这里,在$ES_HOME里,新建一文件,命名为requests。(这里为什么命名为request,去看官网就是)在Linux里,有无后缀没区别。
1 2 3 4 5 6 7 8 9 10 | [hadoop@djt002 elasticsearch-2.4.3]$ vi requests { "index" :{ "_index" : "my_store" , "_type" : "my_index" , "_id" : "11" }} { "price" :10, "productID" : "1111" } { "index" :{ "_index" : "my_store" , "_type" : "my_index" , "_id" : "12" }} { "price" :20, "productID" : "1112" } { "index" :{ "_index" : "my_store" , "_type" : "my_index" , "_id" : "13" }} { "price" :30, "productID" : "1113" } { "index" :{ "_index" : "my_store" , "_type" : "my_index" , "_id" : "14" }} { "price" :40, "productID" : "1114" } |
(2)执行命令
1 2 3 4 5 | curl -PUT '192.168.80.200:9200/_bulk' --data-binary @requests; 或 curl -XPOST '192.168.80.200:9200/_bulk' --data-binary @requests; |
bulk的格式:
{action:{metadata}}\n
{requstbody}\n (请求体)
action:(行为),包含create(文档不存在时创建)、update(更新文档)、index(创建新文档或替换已用文档)、delete(删除一个文档)。
create和index的区别:如果数据存在,使用create操作失败,会提示文档已存在,使用index则可以成功执行。
metadata:(行为操作的具体索引信息),需要指明数据的_index、_type、_id。
示例:
1 | { "delete" :{ "_index" : "lib" , "_type" : "user" , "_id" : "1" }} |
批量添加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | 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 } }, ... ] } |
批量删除
删除的批量操作不需要请求体
1 2 3 4 5 6 7 8 | 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 (请求体)
不用将其转换为json对象,直接按照换行符切割json,内存中不需要json文本的拷贝。
对每两个一组的json,读取meta,进行document路由。
直接将对应的json发送到node上。
为什么不使用如下格式:
[{"action":{},"data":{}}]
1
这种方式可读性好,但是内部处理就麻烦;耗费更多内存,增加java虚拟机开销:
将json数组解析为JSONArray对象,在内存中就需要有一份json文本的拷贝,宁外好友一个JSONArray对象。
解析json数组里的每个json,对每个请求中的document进行路由。
为路由到同一个shard上的多个请求,创建一个请求数组。
将这个请求数组序列化。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步