数据能被es检索到的前提是这些数据在es中进行了存储,数据入es之前必须要创建相应的索引(_index)、类别(_type),以及确定文档的唯一标识(_id)。文档中每个字段的数据要与创建索引时定义的字段类型相匹配,否则索引数据时会报错。
对数据进行维护时难免会遇到并发的情况,比如两个线程同时对同一个字段进行修改,那么以哪个线程修改的为主呢?这样引出了锁的类型:
1、悲观锁:会假设这种并发情况是经常发生的,所以为了防止这种并发情况的发生,当一个线程修改一条数据时就会加锁,此时只有加锁的这个线程才能修改这条数据,直到锁被释放。大部分的关系型数据库都是采用的悲观锁。
2、乐观锁:会假设这种并发情况是不经常发生的,发生时只要返回并发的错误信息,由数据维护的调用者决定是重试还是重新拉取数据再进行操作。es使用的是乐观锁,通过_version来判断是否可以对当前版本的数据进行修改,如果传入的version和实际的version不匹配,那么毫无疑问是不允许进行修改的,修改和删除都接受version参数用于控制并发。另外还可以使用参数version_type=external通过外部版本(比如时间戳等)进行控制,只有传入的外部版本比实际的版本大才可以进行操作,新增、修改和删除都支持传入外部版本号控制并发。
常用API:
一、文档新增
1、新增整个文档(如果$id的文档存在则进行整个文档的修改):
PUT http://$user:$passwd@$host:$port/$index/$type/$id
{
"title": "这是标题的内容",
"content": "这是正文的内容"
}
2、使用_version控制并发,如果有冲突则返回409Conflict,如果无冲突则返回201Created:
PUT http://$user:$passwd@$host:$port/$index/$type/$id?version=5 //修改当前版本_version是5的数据,如果当前版本_version不是5则会报错
{
"title": "这是标题的内容1",
"content": "这是正文的内容1"
}
3、使用外部版本控制并发,如果有冲突则返回409Conflict,如果无冲突则返回201Created:
PUT http://$user:$passwd@$host:$port/$index/$type/$id?timestamp=1573719013&version_type=external //修改数据后外部版本号(timestamp)成为1573719013,如果当前外部版本号(timestamp)大于等于1573719013则报错
{
"title": "这是标题的内容2",
"content": "这是正文的内容2"
}
4、如果不指定$id,es会自动生成一段字符串作为新增文档的_id:
POST http://$user:$passwd@$host:$port/$index/$type/
{
"title": "这是标题的内容3",
"content": "这是正文的内容3"
}
5、使用op_type=create进行文档新增,如果$id已存在,则返回409Conflict:
PUT http://$user:$passwd@$host:$port/$index/$type/$id?op_type=create
{
"title": "这是标题的内容4",
"content": "这是正文的内容4"
}
6、使用_create进行文档新增,如果$id已存在,则返回409Conflict:
PUT http://$user:$passwd@$host:$port/$index/$type/$id/_create
{
"title": "这是标题的内容5",
"content": "这是正文的内容5"
}
更多API请参考:https://www.elastic.co/guide/en/elasticsearch/reference/6.5/docs-index_.html
二、文档修改
1、修改整个文档(原来有某字段但请求中没有该字段时会将该字段删除):
PUT http://$user:$passwd@$host:$port/$index/$type/$id
{
"title": "这是标题的内容",
"content": "这是正文的内容"
}
2、修改文档,增加或修改单个字段,其它字段不改变,如果$id的文档不存时返回404NotFound:
POST http://$user:$passwd@$host:$port/$index/$type/$id/_update
{
"doc":{
"title": "这是标题的内容1"
}
}
3、使用脚本修改文档,新增或修改多个字段用;隔开,如果$id的文档不存时返回404NotFound:
POST http://$user:$passwd@$host:$port/$index/$type/$id/_update
{
"script": {
"source": "ctx._source.title ='这是标题的内容2';ctx._source.count +=3"
}
}
可以简写为:
POST http://$user:$passwd@$host:$port/$index/$type/$id/_update
{
"script": "ctx._source.title ='这是标题的内容3';ctx._source.count +=3"
}
如果同时指定doc
和script
,则将doc
被忽略。
4、根据查询条件修改某个字段:
POST http://$user:$passwd@$host:$port/$index/$type/_update_by_query
{
"script": "ctx._source['title']='这是标题的内容4'",
"query": {
"term": {
"_id": 4
}
}
}
5、使用upsert增补数据,如果文档不存在则用upsert中的内容新增数据,如果文档存在则用script中的内容修改数据:
POST http://$user:$passwd@$host:$port/$index/$type/$id/_update
{
"script": {
"source": "ctx._source.count +=3"
},
"upsert": {
"count" : 1
}
}
如果加入参数:"scripted_upsert":true,则不管文档存不存在,都只执行script中的内容。
6、使用脚本的remove删除某个字段:
POST http://$user:$passwd@$host:$port/$index/$type/$id/_update
{
"script": "ctx._source.remove('content')"
}
7、根据查询条件删除某个字段:
POST http://$user:$passwd@$host:$port/$index/$type/_update_by_query
{
"script": "ctx._source.remove('content')",
"query": {
"bool": {
"must": [
{
"exists": {
"field": "content"
}
}
]
}
}
}
更多API请参考:https://www.elastic.co/guide/en/elasticsearch/reference/6.5/docs-update.html
三、文档删除
1、使用Method是DELETE的请求,成功返回200ok,失败返回404NotFound:
DELETE http://$user:$passwd@$host:$port/$index/$type/$id
2、指定脚本的ctx.op=delete进行删除:
POST http://$user:$passwd@$host:$port/$index/$type/$id/_update
{
"script": "ctx.op='delete'"
}
3、根据查询条件删除,可以设置一些URL参数:
POST http://$user:$passwd@$host:$port/$index/$type/_delete_by_query
{
"query": {
"range" : {
"count" : {
"gte" : 10
}
}
}
}
更多API请参考:https://www.elastic.co/guide/en/elasticsearch/reference/6.5/docs-delete-by-query.html
四、批量操作
批量操作_bulk只支持:index、create、update和delete,四种操作可以混合起来使用,body体中每行行末都有一个换行字符\n:
1、批量新增 (如果$id的文档存在则进行更新):
POST http://$user:$passwd@$host:$port/$index/$type/_bulk
{"index":{"_id":"1"}}
{"title": "这是标题的内容1","content": "这是正文的内容1"}
{"index":{"_id":"2"}}
{"title": "这是标题的内容2","content": "这是正文的内容2"}
2、批量新增 (如果$id的文档存在则报错):
POST http://$user:$passwd@$host:$port/$index/$type/_bulk
{"create":{"_id":"1"}}
{"title": "这是标题的内容1","content": "这是正文的内容1"}
{"create":{"_id":"2"}}
{"title": "这是标题的内容2","content": "这是正文的内容2"}
3 、批量修改(如果$id的文档不存在则报错):
POST http://$user:$passwd@$host:$port/$index/$type/_bulk
{"update":{"_id":"1"}}
{"doc":{"title": "这是标题的内容1","content": "这是正文的内容1"}}
{"update":{"_id":"2"}}
{"doc":{"title": "这是标题的内容2","content": "这是正文的内容2"}}
4 、批量删除(如果$id的文档不存在则报错):
POST http://$user:$passwd@$host:$port/$index/$type/_bulk
{"delete":{"_id":"1"}}
{"delete":{"_id":"2"}}
5 、混合批量删除:
POST http://$user:$passwd@$host:$port/$index/$type/_bulk
{"index":{"_id":"1"}}
{"title": "这是标题的内容1","content": "这是正文的内容1"}
{"create":{"_id":"2"}}
{"title": "这是标题的内容2","content": "这是正文的内容2"}
{"update":{"_id":"3"}}
{"doc":{"title": "这是标题的内容3","content": "这是正文的内容3"}}
{"delete":{"_id":"4"}}
更多API请参考:https://www.elastic.co/guide/en/elasticsearch/reference/6.5/docs-bulk.html