es更新会先查询,将查询到的数据在 .del 文件中标记为删除,新版本文档被索引到新的段中,因为es中segments具有不可变性,此时查询还可查到更新的数据,只是在结果返回时将标记删除的版本文档标记移除。
1.覆盖更新
1.1 POST/PUT更新
put覆盖更新,当传入的字段不全式,更新后,只会有部分字段。特别注意数据的完整性。
PUT user_info_001
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
},
"mappings": {
"properties": {
"userId": {
"type": "integer"
},
"name": {
"type": "keyword"
},
"age":{
"type": "integer"
}
}
}
}
PUT user_info_001/_doc/1
{
"userId":1001,
"name":"william",
"age":22
}
#更新,传入所有字段
PUT user_info_001/_doc/1?refresh=true
{
"userId":1001,
"name":"james",
"age":37
}
#覆盖式更新,如果只传入部分字段,则更新后只会保留部分字段。
PUT user_info_001/_doc/1?refresh=true
{
"name":"james"
}
1.2 req请求参数
if_seq_no:并发顺序号
if_primary_term:并发更新主分片顺循号
version:并发版本号
version_type:并发版本类型
op_type:数据写入类型,create/updated/noop
refresh:是否立即刷新
routing:路由
wait_for_active_shards:写入数据等待分片数响应数
pipeline:数据ETL处理
1.3 rep响应参数
_id:唯一id
result:写入数据结构,create/updated/noop
version:数据版本号
_seq_no:索引更新顺序号
_primary_term:主分片任期号
_shards.xx:数据更新到分片的成功信息
2.局部更新
使用_update局部更新接口,doc中写要更新的内容,doc_as_upsert 是否存在更新,取值true/false,不存在则插入,插入时,doc中的内容作为全部的字段属性。
原理是,更新的字段会与服务端原始数据进行合并,所以原始数据_source必须启用。
#插入数据
PUT user_info_001/_doc/1
{
"userId":1001,
"name":"william",
"age":22
}
#局部更新
POST user_info_001/_update/1?refresh=true
{
"doc":{
"name":"james"
}
}
#doc_as_upsert
POST user_info_001/_update/11?refresh=true
{
"doc":{
"income" : 2000,
"name" : "bill",
"cityId" : 601020,
"userId" : 10021,
"age" : 27
},
"doc_as_upsert":true
}
GET user_info_001/_search
3.脚本更新
3.1 script 脚本更新
关键字 script 他有几个属性。source用来写脚本 需要用三个引号包起来,lang表示脚本语言,params 表示脚本参数,下面看两个栗子。
POST user_info_001/_update/1?refresh=true
{
"script": {
"source": """
ctx._source.name="kobe";
""",
"lang": "painless",
"params": {}
}
}
#也可以使用 Params 进行设置参数
POST user_info_001/_update/1?refresh=true
{
"script": {
"source": """
ctx._source.name=params.name;
ctx._source.age=params.age;
"""
, "lang": "painless",
"params": {
"name":"paul",
"age":28
}
}
}
3.2 req请求参数
? if_seq_no,解决数据更新版本冲突
? if_primary_term,解决数据更新版本冲突
? retry_on_conflict,解决数据更新版本冲突,重试次数,默认0
? lang,脚本更新语言设置,默认painless,ES支持3种
? refresh,索引是否立即刷新
? routing,数据更新路由
? wait_for_active_shards,数据更新分片设置
3.3 rep响应参数
? result,更新结果,updated,noop空操作
? _version,数据更新后的版本号
? _shards,分片更新成功数
? _seq_no,数据更新版本顺序号
? _primary_term,主分片序号
4.批量更新
Bulk更新本质是采用局部更新实现的,无需要客户端完整的数据,但支持的灵活性有限,不可以使用脚本,仅支持数据填充方式。
bluk:批量更新关键字
update,局部更新关键字
doc_as_upsert,支持插入式更新
POST _bulk
{"update":{"_index":"user_info_001","_id":"1"}}
{ "doc":{"userId":1005,"name":"bryant","age":19}}
{"update":{"_index":"user_info_001","_id":"2"}}
{ "doc":{"userId":1006,"name":"paul","age":22}}