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之間。

相關文章
相關標籤/搜索