Elasticsearch之数据维护

       数据能被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"
}

       如果同时指定docscript,则将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

发布了108 篇原创文章 · 获赞 31 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/lzghxjt/article/details/102771348