ElasticSearch汇总请查看:ElasticSearch教程——汇总篇
本博客所有操作均基于Kibana,基础详情见ElasticSearch教程——Kibana简单操作ES
批量查询
优点:能够大大减少网络的请求次数,缩减网络开销。
(1)自定义设置index、type以及document id
GET /_mget
{
"docs" : [
{
"_index" : "ecommerce",
"_type" : "product",
"_id" : 1
},
{
"_index" : "ecommerce",
"_type" : "product",
"_id" : 2
}
]
}
返回结果如下
id为1的没有查到(found为false)
{
"docs": [
{
"_index": "ecommerce",
"_type": "product",
"_id": "1",
"found": false
},
{
"_index": "ecommerce",
"_type": "product",
"_id": "2",
"_version": 2,
"found": true,
"_source": {
"name": "jiajieshi yagao",
"desc": "youxiao fangzhu",
"price": 25,
"producer": "jiajieshi producer",
"tags": [
"fangzhu"
]
}
}
]
}
(2)在对应的index、type下进行批量查询
注意:在ElasticSearch6.0以后一个index下只能有一个type,否则会报错
GET /ecommerce/product/_mget
{
"ids": [2, 3]
}
或者
GET /ecommerce/product/_mget
{
"docs" : [
{
"_id" : 2
},
{
"_id" : 3
}
]
}
返回结果
{
"docs": [
{
"_index": "ecommerce",
"_type": "product",
"_id": "2",
"_version": 2,
"found": true,
"_source": {
"name": "jiajieshi yagao",
"desc": "youxiao fangzhu",
"price": 25,
"producer": "jiajieshi producer",
"tags": [
"fangzhu"
]
}
},
{
"_index": "ecommerce",
"_type": "product",
"_id": "3",
"_version": 1,
"found": true,
"_source": {
"name": "zhonghua yagao",
"desc": "caoben zhiwu",
"price": 40,
"producer": "zhonghua producer",
"tags": [
"qingxin"
]
}
}
]
}
基于bulk的增删改
bulk语法
- delete:删除一个文档,只要1个json串就可以了
- create:PUT /index/type/id/_create,强制创建
- index:普通的put操作,可以是创建文档,也可以是全量替换文档
- update:执行的partial update操作
注意点
1.bulk api对json的语法有严格的要求,除了delete外,每一个操作都要两个json串,且每个json串内不能换行,非同一个json串必须换行,否则会报错;
2.bulk操作中,任意一个操作失败,是不会影响其他的操作的,但是在返回结果里,会告诉你异常日志;
创建文档index
未指定id时,系统会自动创建id
POST /_bulk
{ "index": { "_index": "ecommerce", "_type":"product"}}
{ "name": "test yagao", "desc": "youxiao fangzhu"}
返回结果
{
"took": 19,
"errors": false,
"items": [
{
"index": {
"_index": "ecommerce",
"_type": "product",
"_id": "KXfSFWYBBoLynJN1TUPo",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 9,
"_primary_term": 2,
"status": 201
}
}
]
}
强制创建文档create
POST /_bulk
{ "create": { "_index": "ecommerce", "_type": "product", "_id": "4" }}
{ "test_field": "test12" }
返回结果
{
"took": 88,
"errors": false,
"items": [
{
"create": {
"_index": "ecommerce",
"_type": "product",
"_id": "4",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 6,
"_primary_term": 2,
"status": 201
}
}
]
}
修改文档update
POST /_bulk
{ "update": { "_index": "ecommerce", "_type": "product", "_id": "4","retry_on_conflict" : 3 }}
{ "doc" : {"test_field" : "test update"} }
返回结果
{
"took": 1,
"errors": false,
"items": [
{
"update": {
"_index": "ecommerce",
"_type": "product",
"_id": "4",
"_version": 2,
"result": "noop",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"status": 200
}
}
]
}
删除文档delete
POST /_bulk
{ "delete": { "_index": "ecommerce", "_type": "product", "_id": "4"}}
返回结果
{
"took": 12,
"errors": false,
"items": [
{
"delete": {
"_index": "ecommerce",
"_type": "product",
"_id": "4",
"_version": 3,
"result": "deleted",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 8,
"_primary_term": 2,
"status": 200
}
}
]
}
bulk api奇特的json格式
目前处理流程
- 直接按照换行符切割json,不用将其转换为json对象,不会出现内存中的相同数据的拷贝;
- 对每两个一组的json,读取meta,进行document路由;
- 直接将对应的json发送到node上去;
换成良好json格式的处理流程
- 将json数组解析为JSONArray对象,这个时候,整个数据,就会在内存中出现一份一模一样的拷贝,一份数据是json文本,一份数据是JSONArray对象;
- 解析json数组里的每个json,对每个请求中的document进行路由;
- 为路由到同一个shard上的多个请求,创建一个请求数组;
- 将这个请求数组序列化;
- 将序列化后的请求数组发送到对应的节点上去;
奇特格式的优缺点
缺点:可读性差;
优点:不需要将json数组解析为一个JSONArray对象,形成一份大数据的拷贝,浪费内存空间,能够尽可能地保证性能;
例如:
bulk size最佳大小一般建议说在几千条,大小在10MB左右。假设说现在100个bulk请求发送到了一个节点上去,然后每个请求是10MB,100个请求,就是1000MB = 1GB,然后每个请求的json都copy一份为jsonarray对象,此时内存中的占用就会翻倍,就会占用2GB的内存,甚至还不止。因为弄成jsonarray之后,还可能会多搞一些其他的数据结构,2GB+的内存占用。
占用更多的内存可能就会积压其他请求的内存使用量,比如说最重要的搜索请求,分析请求,等等,此时就可能会导致其他请求的性能急速下降。
另外的话,占用内存更多,就会导致java虚拟机的垃圾回收次数更多,跟频繁,每次要回收的垃圾对象更多,耗费的时间更多,导致es的java虚拟机停止工作线程的时间更多。