Elasticsearch 增删改

一部分的原理及restful api操做示例,包括新增,删除,修改和批量操做。es版本为7.3.0。es6.5以后淡化了type,建议type都使用_doc类型

增删改操做的机制node

(当number_of_replicas>1时才生效)
发送任何一个增删改操做的时候,如POST /index/_doc/id,均可以带上一个consistency参数,指明对于写一致性的规则,三个选项one,all,quorum(default)
one:这个写操做,只要有一个primary shard是active活跃可用的,就能够执行
all:这个写操做,必须全部的primary shard和replica shard都是活跃的,才能够行
quorum:默认的值,要求全部的shard中,必须大部分的shard都是活跃的,可用的,才能够执行。大于((primary + number_of_replicas) / 2) + 1,quorum不齐全时,wait,默认1分钟,也能够指定timeout参数,timeout=30 单位s

新增:

POST /{index}/_doc/{id}
{
  "{fieldname}":"{fieldvalue}"
}
能够指定id,也能够不指定,es会默认生成_id字段的值,es建立的id,长度为20个字符,base64编码,支持分布式。
  • document的全量替换:

    新增数据时id不存在就是建立,存在就是全量替换,es会将老的document标记为deleted,而后新增给定的一个documentes6

  • document的强制建立:
    POST /{index}/_doc/{id}?op_type=create
    POST /{index}/_doc/{id}/_create
    若是id已经存在会建立失败put和post均可以

删除:

删除文档

DELETE /{index}/_doc/{id}
不会物理删除,只会将其标记为deleted,当数据愈来愈多的时候,在后台自动删除json

delete by query

by query这种方式,数据老化方式性能慢,并且执行后,底层并不必定会释放磁盘空间,后期 merge 也会有很大的性能损耗,对正常业务影响巨大。api

POST /index/_delete_by_query
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "fieldname": "fieldvalue"
          }
        },
        {
          "prefix": {
            "fieldname1": {
              "value": "value1"
            }
          }
        }
      ]
    }
  }
}

删除索引:

支持通配符,如:
DELETE /{inde*}
DELETE /_all
删除全部索引须要修改配置文件elasticsearch.yml
action.destructive_requires_name: true数组

修改:

新增时id存在时会修改所有,partial update(修改个别字段)案例以下:restful

POST /{index}/_update/{id}
{
  "doc": {
    "{fieldname}": "{fieldvalue}"
  }
}
必须是post请求,底层是将_source字段取出,而后修改对应字段,最后作全量替换,同时也会执行乐观锁的并发控制,索引的mapping若是没有开启_source,不能执行此操做。

乐观锁的并发控制

  • 基于version修改
    PUT /{index}/_doc/{id}?version={2}&version_type=external 并发

    只有当你提供的version比es中的_version大的时候,才能完成修改
  • 内置脚本修改
POST /{index}/_update/{id}
{
   "script" : "ctx._source.{fieldname}+={value}"
}
字符串类型也能够调用内置的方法

retry_on_conflict:

(可选,整数)指定发生冲突时应重试操做多少次。默认值:0
直接在查询参数添加?retry_on_conflict=0app

upsert:

若是文档还不存在,upsert元素的内容将做为新文档插入。若是文档存在,则执行脚本。less

POST index/_update/id
{
  "script": {
    "source": "ctx._source.fieldname += params.count",
    "lang": "painless",
    "params": {
      "count": 2
    }
  },
  "upsert": {
    "fieldname": 1
  }
}

update by query:

POST /index/_update_by_query
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "fieldname": "fieldvalue"
          }
        },
        {
          "prefix": {
            "fieldname1": {
              "value": "value1"
            }
          }
        }
      ]
    }
  }
}

批量操做,bulk API:

POST /{index}/_bulk
{ "delete": {  "_id": "{id1}" }}
{ "create": {"_id": "{id2}" }} 
{ "{fieldname1}": "{fieldvalue1}" }
{ "index":  {  "_id": "{id3}" }} 
{ "{fieldname2}": "{fieldvalue2}"}                                        
{ "update": {  "_id": "{id4}"} }
{ "doc" : {"{fieldname3}": "{fieldvalue3}"} }

能够执行的操做:
delete:删除一个文档,只要1个json串就能够了
create:PUT /index/type/id/_create,强制建立
index:普通的put操做,能够是建立文档,也能够是全量替换文档
update:执行的partial update操做jvm

bulk api对json的语法,有严格的要求,每一个json串不能换行,只能放一行,同时一个json串和一个json串之间,必须有一个换行,不然会json解析异常,会返回每个操做的结果。任何一个操做失败不影响其余操做,会在对应返回结果中返回异常日志

批量操做原理:

bulk中的每一个操做均可能要转发到不一样的node的shard去执行,若是采用比较良好的json数组格式,
整个可读性很是好,可是es拿到那种标准格式的json串之后,须要将json数组解析为JSONArray对象,
这个时候,整个数据就会在内存中出现一份如出一辙的拷贝,一份数据是json文本,一份数据是JSONArray对象,
而后解析json数组里的每一个json,对每一个请求中的document进行路由接着为路由到同一个shard上的多个请求,
建立一个请求数组,最后将这个请求数组序列化并发送到对应的节点上。耗费更多内存,更多的jvm gc开销

如今的格式:直接按照换行符切割json,对每两个一组的json,读取meta,进行document路由,直接将对应的json发送到node上去

bulk size建议:bulk请求会加载到内存,太大的话,性能反而会降低,所以须要尝试一个最佳的bulk size。通常从1000~5000条数据开始,尝试逐渐增长。大小的话,最好是在5~15MB之间。

相关文章
相关标签/搜索