批量查询 _mget
使用批量查询的好处在于将多次网络请求合并成一个,大大减少了网络消耗,提升ES查询效率。
具体API如下:
GET /_mget
{
"docs":[
{
"_index":"employee",
"_type":"_doc",
"_id":"1"
},{
"_index":"employee",
"_type":"_doc",
"_id":"2"
}
]
}
如果都是查询同样的 index 可以将其提取到请求路径中,像这样:
GET /employee/_mget
{
"docs":[
{
"_type":"_doc",
"_id":"1"
},{
"_type":"_doc",
"_id":"2"
}
]
}
如果 index 和 type 都一样那我们还可以简写成这样:
GET /employee/_doc/_mget
{
"ids":["1","2"]
}
这里三种方式的查询结果是一样的。
这里注意,如果多个查询条件中某一个条件不存在,结果还是会正常返回,仅仅对未查到的那个数据的结果位置中的 fount 字段值为 false,像这样:
"docs" : [
.... ,
{
"_index" : "employee",
"_type" : "_doc",
"_id" : "4",
"found" : false
}, ....
]
批量写 _bulk
_bulk API允许我们在一次请求中执行多次 create、index、update、delete等操作。
通常还是批量写入较多,比如日志写入ES就可以使用 _bulk,API 语法如下:
{ action: { metadata }}\n
{ request body }\n
{ action: { metadata }}\n
{ request body }\n
......
这里需要注意:
- action 只能为 create、index、update、delete,各选项的意义如下:
- create 当且仅当文档不存在时,创建新文档
- index 创建一个新文档或者是全量更新旧文档
- update 局部更新文档
- delete 删除文档
- metadata 用来设置像这样的元数据:_index、_type、_id
- request body 可以理解为 _source 的内容
- 每行一定要以换行符(\n)结尾, 包括最后一行 。这些换行符被用作一个标记,可以有效分隔行
- 这些行不能包含未转义的换行符,因为他们将会对解析造成干扰。这意味着这个 JSON 不 能使用 pretty 参数打印。
这种每条命令以换行符结尾的格式使得ES可以无需做过多解析就可以将命令分发到各自对应的节点执行。
这里我们通过 _bulk 来做一次批量新增:
POST _bulk
{"create":{"_index":"technology","_type":"_doc","_id":"1"}}
{"name":"Java"}
{"create":{"_index":"technology","_type":"_doc","_id":"2"}}
{"name":"Javascript"}
{"create":{"_index":"technology","_type":"_doc","_id":"3"}}
{"name":"css"}
返回结果如下:
{
"took" : 141,
"errors" : false,
"items" : [
{
"create" : {
"_index" : "technology",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 2,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1,
"status" : 201
}
},
{
"create" : {
"_index" : "technology",
"_type" : "_doc",
"_id" : "2",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 2,
"failed" : 0
},
"_seq_no" : 1,
"_primary_term" : 1,
"status" : 201
}
},
{
"create" : {
"_index" : "technology",
"_type" : "_doc",
"_id" : "3",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 2,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1,
"status" : 201
}
}
]
}
这些字段都不陌生,就不多解释了。
index 和 update 和 create 操作类似,而 delete 动作不能有请求体,所以这里在给一个 delete 的实例:
POST _bulk
{"delete":{"_index":"technology","_type":"_doc","_id":"1"}}
{"delete":{"_index":"technology","_type":"_doc","_id":"2"}}
返回结果与上面一样,只是 result 的值为 deleted。
和 _mget API一样, _bulk 的多个操作中若某一个失败不会影响其他命令执行,它们是互相独立的。
注意
虽然批量操作可以提升性能,但不是说可以将无限多的命令通过 _bulk API一次执行,当执行的命令条数到达一定数量级的时候,性能反而会下降,所以这里我们需要自己测试出机器的最佳性能的所执行的命令条数。并且还需注意 _source 字段的数据量不要过大,否则也会有同样的问题。