文档局部更新
POST /website/blog/1/_update
{
"doc" : {
"tags" : [ "testing" ],
"views": 0
}
}
使用脚本局部更新
使用Groovy脚本
这时候当API不能满足要求时,Elasticsearch允许你使用脚本实现自己的逻辑。脚本支持非常多的API,例如搜索、排序、聚合和文档更新。脚本可以通过请求的一部分、检索特殊的.scripts索引或者从磁盘加载方式执行。
默认的脚本语言是Groovy,一个快速且功能丰富的脚本语言,语法类似于Javascript。它在一个沙盒(sandbox)中运行,以防止恶意用户毁坏Elasticsearch或攻击服务器。
你可以在《脚本参考文档》中获得更多信息。
脚本能够使用update API改变_source字段的内容,它在脚本内部以ctx._source表示。例如,我们可以使用脚本增加博客的views数量:
POST /website/blog/1/_update
{
"script" : "ctx._source.views+=1"
}
我们还可以使用脚本增加一个新标签到tags数组中。在这个例子中,我们定义了一个新标签做为参数而不是硬编码在脚本里。这允许Elasticsearch未来可以重复利用脚本,而不是在想要增加新标签时必须每次编译新脚本:
POST /website/blog/1/_update
{
"script" : "ctx._source.tags+=new_tag",
"params" : {
"new_tag" : "search"
}
}
通过设置ctx.op为delete我们可以根据内容删除文档:
POST /website/blog/1/_update
{
"script" : "ctx.op = ctx._source.views == count ? 'delete' : 'none'",
"params" : {
"count": 1
}
}
更新可能不存在的文档
想象我们要在Elasticsearch中存储浏览量计数器。每当有用户访问页面,我们增加这个页面的浏览量。但如果这是个新页面,我们并不确定这个计数器存在与否。当我们试图更新一个不存在的文档,更新将失败。
在这种情况下,我们可以使用upsert参数定义文档来使其不存在时被创建。
POST /website/pageviews/1/_update
{
"script" : "ctx._source.views+=1",
"upsert": {
"views": 1
}
}
第一次执行这个请求,upsert值被索引为一个新文档,初始化views字段为1.接下来文档已经存在,所以script被更新代替,增加views数量。
浏览器的自增浏览量:
POST /website/pageviews/1/_update?retry_on_conflict=5 <1>
{
"script" : "ctx._source.views+=1",
"upsert": {
"views": 0
}
}
<1> 在错误发生前重试更新5次
这适用于像增加计数这种顺序无关的操作。
bulk批量更新
更新的时候 如果用了parent,一定要把parent也加上。
$bulkParams = ['type' => "wechat_customer_tag"];
foreach ($openids as $row) {
if (isset($row["id"]) && $row["id"] && isset($row["id"]) && $row["id"]) {
$bulkParams['body'][] = ['update' => ['_id' => $row["id"],'parent' => $row["openid"]] ];
$bulkParams['body'][] = array("doc" => array("status" => $row['status'], "count" => $row['count']));
}
}
if (isset($bulkParams['body'])) {
ElasticsearchClient::bulk($bulkParams, $mid);
unset($bulkParams);
}