关于elasticsearch:elasticsearch笔记006文档APICRUD单文档更新操作

[toc]

1. 单文档 Update API

update API 依据提供的script更新文档; 从索引中获取document, 执行脚本, 并对新的后果进行索引.

如何确保 get 和 reindex 期间没有产生更新? –> 应用版本控制;

这种操作依然意味着对文档进行残缺的从新索引, 它只是移除了一些网络往返损耗,并缩小了get和索引之间版本抵触的机会.

1. script更新: 数值计算

示例: 新建一个document到 test 索引, 而后批改 counter=counter+4; 而后为tags新增一个 blue的色彩:

#1. 新建一个document到 test 索引
PUT test/_doc/1
{
    "counter" : 1,
    "tags" : ["red"]
}

将 “counter”的值加上给定的参数:

POST test/_update/1
{
    "script" : {
        "source": "ctx._source.counter += params.count",
        "lang": "painless",
        "params" : {
            "count" : 4
        }
    }
}

查看以后: GET test/_source/1

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

同理: counter=counter*2:

POST test/_update/1
{
  "script": {
    "source": "ctx._source.counter *= params.val",
    "params": {
      "val": 2
    }
  }
}

2. script更新: 数组(汇合)减少/删除

2.1 减少一个 yellow:

POST test/_update/1
{
  "script": {
    "source": "ctx._source.tags.add(params.clr)",
    "params": {"clr": "yellow"}
  }
}

output:

{
    "counter" : 10,
    "tags" : [
      "red",
      "yellow"
    ]
}

2.2 删除(留神是索引)

理论是ArrayList的办法!

POST test/_update/1
{
  "script": {
    "source": "ctx._source.tags.remove(params.val)",
    "params": {
      "val": 0
    }
  }
}
{
    "counter" : 10,
    "tags" : [ "yellow" ]
}

2.3 clear()清空

同理, 能够调用 ArrayList的其余办法: 比方 :

POST test/_update/1
{
  "script": {
    "source": "ctx._source.tags.clear()"
  }
}

2.4 如何删除匹配的内容

如果当初 tags = [“yello”, “red”, “blue”], 要删除 “red”, 依据内容而非索引:

POST test/_update/1
{
  "script": {
    "source": "if (ctx._source.tags.contains(params.val)) {ctx._source.tags.remove(ctx._source.tags.indexOf(params.val));}",
    "params": {
      "val": "red"
    }
  }
}

GET test/_source/1 output:

{
    "counter" : 10,
    "tags" : [
      "yellow",
      "blue"
    ]
}

留神: script.source 里的”;”能够不要的;

2.5 script更新: ctx的其余内置变量

除了 _source 之外,ctx映射还提供了以下变量: _index_type_id_version_routing_now(以后工夫戳)。

2.6 script更新: 减少/删除字段entry

咱们给 test 索引中的 文档 1 新增一个字段: “addr”: “beijing”:

# update 减少字段entry
POST test/_update/1
{
  "script": {
    "source": "ctx._source.addr='beijing'"
    }
}
# 再减少一条
POST test/_update/1
{
  "script": {
    "source": "ctx._source.location='yizhuang'"
    }
}

GET test/_source/1

{
  "counter" : 10,
  "tags" : [
    "yellow"
  ],
  "addr" : "beijing",
  "location" : "yizhuang"
}

删除:

# update 删除字段
POST test/_update/1
{
  "script": {
    "source": "ctx._source.remove('location')"
  }
}

GET test/_source/1 :

{
  "counter" : 10,
  "tags" : [
    "yellow"
  ],
  "addr" : "beijing"
}

3. doc新增字段:

除了应用 script 外, 也能够应用 doc 来新增字段; 如果二者皆有, 会报错!

POST test/_update/1
{
    "doc" : {
        "loc" : "yz"
    }
}
{
  "counter" : 10,
  "tags" : [
    "yellow"
  ],
  "addr" : "beijing",
  "loc" : "yz"
}

如果指定了doc,那么它的值将与现有的_source合并; 如果 doc执行了屡次, 数据并没有变动, \_version和 \_seq\_no都不会更新! "result" : "noop"

4. upsert 更新+插入

4.1 script+upsert形式

如果文档还不存在,那么upsert元素的内容将作为新文档插入。如果该文档存在,则执行脚本:

DELETE test/_doc/2 咱们先执行此操作删除id=2的document; 而后执行上面 upsert 操作:

POST test/_update/2
{
    "script" : {
        "source": "ctx._source.counter += params.count",
        "lang": "painless",
        "params" : {
            "count" : 4
        }
    },
    "upsert" : {
        "counter" : 2,
        "name": "ifnotexists"
    }
}

因为此刻没有 id=2的文档, 所以默认+=操作时是不会有的; 这样的话, upsert中的内容就会作为文档的内容保留;

这是 反复下面的 upsert 操作一次!! 再查后果: GET test/_source/2

{
  "counter" : 6,
  "name" : "ifnotexists"
}

能够看到, counter就是 2+4了;

4.2 doc形式的upsert

doc形式也能够实现upsert: 如下: 如果单纯是在下面有id=2的document的根底上执行上面:

POST test/_update/2
{
  "doc": {
    "gender": "male"
  },
  "doc_as_upsert": true
}

只是减少了一个 gender的字段!

{
  "counter" : 6,
  "name" : "ifnotexists",
  "gender" : "male"
}

当初删掉document: DELETE test/_doc/2 , 就会体现为 upsert的性能了, 此时 GET test/_source/2:

{"gender" : "male"}

5. update的其余参数

timeout/wait_for_active_shards/version, 以及 if_seq_no + if_primary_term

5.1 if_seq_no+if_primary_term

POST test/_update/2?if_seq_no=31&if_primary_term=1
{
  "script": {
    "source": "ctx._source.counter=params.val",
    "params": {
      "val": 3
    }
  }
}

如果 _seq_no_primary_term匹配, 才执行更新, 否则报错!

2. TODO: Update By Query API

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理