es数据写入、删除和更新
转载于: https://www.jianshu.com/p/d9e5451456e6
数据写入过程:
注:一个数据不会写入多个主分片
注:数据先写入Buffer,同时写入Translog(用于极端情况下的数据恢复),Buffer缓存数据达到阈值会批量刷到磁盘(中间有个文件系统缓冲),所以说es的数据写入是一个近实时的(存才延时默认是1秒)
单条写入put/post:
1、put,需要设定数据ID(同一条数据首次插入是created,再次插入会updated)
2、post,可选择设定数据ID(不指定id情况下:同一条数据首次插入是created,再次插入还是created,但_id会变;指定id若id不变第二次插入失败)
_doc:同一条数据首次插入是created,再次插入会updated
_create:同一条数据首次插入是created,再次插入会报错
PUT compyan-starff-001/_doc/1
{
...
}
PUT compyan-starff-001/_create/1
{
...
}
result,created/updated,新增或更新
req请求参数解读:
op_type,操作类型
refresh,刷新策略
PUT compyan-starff-001/_doc/1?routing=1 #路由到第一个主分片
{
...
}
routing,路由策略
Wait_for_active_shards,等待写入分片数量
GET company-staff-001/_doc/1 #通过这种方式可以立即获取到插入的数据,因为这种GET方式会直接
#从Buffer中回去数据(实时)
GET company-staff-001/_search?routing=1 #_search需要路由到指定的分段从磁盘中获取数据(这种是非实时)
#PUT数据时可以通过&refresh=true强制实时(也是近实时)
批量写入_bulk:
POST _bulk
{index:{"_index":"company-staff-001", "_id": "1"}}
...
{index:{"_index":"company-staff-001", "_id": "2"}}
...
{index:{"_index":"company-staff-001", "_id": "3"}}
...
数据删除:
删除的路由机制和写入的路由机制相同
DELETE company-staff-001/_doc/1
#如插入数据时_version为1,删除是版本号为_version为2,原因:标记删除先更新了数据版本发生变化,默认情况编辑删除的数据能保存24小时
条件删除:_delete_by_query
POST kibana_sample_data_logs_delete/_delete_by_query?requests_per_second
{
"slice":{ #手动分片删除
"id":1, #两次删除需要修改id
"max":2 #分为两批次删除
}
"query": {
"match_all": {}
}
}
POST kibana_sample_data_logs_delete/_delete_by_query?slice=2&scroll_size=1000&requests_per_second=100
#自动分片删除,最大的片数不能超过自己的分片数
requests_per_second:每秒删除多少条数据
注:一般需要加上requests_per_second来控制删除;若不加,在条件删除海量数据时,可能执行时间比较长,造成es瞬间io巨大,属于危险操作
scroll_size:每次从es遍历多少条数据存储到Buffer中
requests_per_second:每秒多少条
GET _cat/tasks #查询所有任务
GET _tasks?detailed=true&actions=*/delete/byquery #查询上面的删除任务
批量删除:
POST _bulk?refresh=true #刷新
{"delete":{"_index":"company-staff-001", "_id":"1"}}
{"delete":{"_index":"company-staff-001", "_id":"2"}}
{"delete":{"_index":"company-staff-001", "_id":"3"}}
mysql数据库批量导入数据到es可以使用logstash,原理就是使用了"_bulk"命令
思考:批量输出数据,当数据量过大时,不如直接删除索引,再重新导入数据
更新
1、全量更新
#第二次put会全量更新
POST compyan-starff-001/_doc/1
{
...
}
2、局部更新
POST compyan-starff-001/_update/1
{
"_doc":{
"companyName":"xx公司"
}
#重要:false当id为1的记录不存在时会更新报错,true当id为1的记录不存在时会创建索引并插入记录
"doc_as_upset":true
}
3、脚本更新
只更新记录中companyName字段内容
POST compyan-starff-001/_update/1?refresh=true
{
"script":{
"source":"""
ctx._source. companyName="aaa公司";
""",
"lang":"painless",
"params":{}
}
}
或
POST compyan-starff-001/_update/1?refresh=true
{
"script":{
"source":"""
ctx._source. companyName=params.cName;
""",
"lang":"painless",
"params":{
"cName":"aaa公司"
}
}
}
或
POST compyan-starff-001/_update/1?refresh=true
{
"upsert":{
"companyName"="aaa公司"
}
}
批量更新_bulk:
POST _bulk?refresh=true
{"upadte":{"_index":"compyan-starff-001","_id":"1"}}
{"_doc":{"compaynId":"2020","userId":"1234"}}
{"upadte":{"_index":"compyan-starff-001","_id":"2"}}
{"_doc":{"compaynId":"2021","userId":"12345"}}
{"upadte":{"_index":"compyan-starff-001","_id":"3"}}
{"_doc":{"compaynId":"2022","userId":"123456"}}
"result":"noop"表示跟进前后数据相同,es没有做操作,(es会先做检查)
"_version"当更新不成功时,版本号依然会加1,若要指定版本号,可以外部设置,但是版本号必须必目前版本号大,否则报错
条件更新:
"_update_by_query"和条件删除类似
作者:奋斗的韭菜汪
链接:https://www.jianshu.com/p/d9e5451456e6
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。