Elasticsearch 2.20 文檔篇:更新刪除文檔

Porter4195 8年前發布 | 59K 次閱讀 ElasticSearch 搜索引擎

來自: http://my.oschina.net/secisland/blog/614513


    Elasticsearch的更新文檔API準許通過腳本操作來更新文檔。更新操作從索引中獲取文檔,執行腳本,然后獲得返回結果。它使用版本號來控制文檔獲取或者重建索引。

 備注:在Elasticsearch中的更新操作是完全從新索引文件。

    我們新建一個文檔:

請求:PUT http://localhost:9200/test/type1/1?pretty

參數:

{
    "counter" : 1,
    "tags" : ["red"]
}

腳本開啟功能

    在最新版本的Elasticsearch中,基于安全考慮(如果用不到,請保持禁用),默認禁用了動態腳本功能.如果被禁用,在使用腳本的時候則報以下的錯誤:

scripts of type [inline], operation [update] and lang [groovy] are disabled

    可以用以下方式完全開啟動態腳本功能,在config/elasticsearch.yml文件,在最后添加以下代碼

script.inline: on

script.indexed: on

script.file: on

配置后,重啟Elasticsearch。

下面我們用腳本來更新此文檔。

請求:POST http://localhost:9200/test/type1/1/_update?pretty

參數:

{
    "script" : {
        "inline": "ctx._source.counter += count",
        "params" : {
            "count" : 4
        }
    }
}

執行完后,我們在查詢一下文檔內容,可以發現counter的值為5:

{
  "_index" : "test",
  "_type" : "type1",
  "_id" : "1",
  "_version" : 5,
  "found" : true,
  "_source" : {
    "counter" : 5,
    "tags" : [ "red" ]
  }
}

在看下面的更新操作:

請求:POST http://localhost:9200/test/type1/1/_update?pretty

參數:

{
    "script" : {
        "inline": "ctx._source.tags += tag",
        "params" : {
            "tag" : "blue"
        }
    }
}

返回的內容為,表示更新成功,我們看一下_version為6,比剛才的值增加了1:

{
  "_index" : "test",
  "_type" : "type1",
  "_id" : "1",
  "_version" : 6,
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  }
}

然后我們在查詢一下文檔內容:

{
  "_index" : "test",
  "_type" : "type1",
  "_id" : "1",
  "_version" : 6,
  "found" : true,
  "_source" : {
    "counter" : 5,
    "tags" : [ "red", "blue" ]
  }
}

在腳本中除了_source外其他內置參數也可以使用,例如_index, _type, _id, _version, _routing, _parent, _timestamp, _ttl。

下面我們通過腳本增加一列。

請求:POST http://localhost:9200/test/type1/1/_update?pretty

參數:

{
    "script" : "ctx._source.name_of_new_field = \"value_of_new_field\""
}

然后查詢此文檔:

{
  "_index" : "test",
  "_type" : "type1",
  "_id" : "1",
  "_version" : 7,
  "found" : true,
  "_source" : {
    "counter" : 5,
    "tags" : [ "red", "blue" ],
    "name_of_new_field" : "value_of_new_field"
  }
}

從中可以看出,文檔中又增加了一列。

刪除一列,請求和剛才的一樣,參數變為:

{
    "script" : "ctx._source.remove(\"name_of_new_field\")"
}

甚至可以通過表達式來判斷做某些事情,例如:下面的示例將刪除的文件如果標簽字段包含藍色,否則什么也不做(空):

請求參數:

{
    "script" : {
        "inline": "ctx._source.tags.contains(tag) ? ctx.op = \"delete\" : ctx.op = \"none\"",
        "params" : {
            "tag" : "blue"
        }
    }
}

部分文檔更新:

    該更新接口還支持更新部分文檔,將文檔合并到現有文檔中(簡單的遞歸合并、對象的內部合并、替換核心的“鍵/值”和數組)。例如:

{
    "doc" : {
        "name" : "new_name"
    }
}

更新后,可以發現文檔中多了一列name。

{
  "_index" : "test",
  "_type" : "type1",
  "_id" : "1",
  "_version" : 23,
  "found" : true,
  "_source" : {
    "counter" : 5,
    "tags" : [ "red", "blue" ],
    "name" : "new_name"
  }
}

    當文檔指定的值與現有的_source合并。當新的文檔和老的文檔不一致的時候,文檔將會被從新建立索引。當新舊文檔一樣的時候,則不進行從建索引的操作。可以通過設置detect_noop為false,讓任何情況下都從新建立索引,例如下面的更新操作:

{
    "doc" : {
        "name" : "new_name"
    },
    "detect_noop": false
}

刪除文檔

    刪除文檔相對比較簡單:

請求:DELETE http://localhost:9200/test/type1/1

返回的內容為:

{
    "found": true, 
    "_index": "test", 
    "_type": "type1", 
    "_id": "1", 
    "_version": 24, 
    "_shards": {
        "total": 2, 
        "successful": 1, 
        "failed": 0
    }}

則表示刪除了此文檔。

    賽克藍德(secisland)后續會逐步對Elasticsearch的最新版本的各項功能進行分析,近請期待。也歡迎加入secisland公眾號進行關注。

 本文由用戶 Porter4195 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!