用ES的时候常常会遇见更新数据的情况,
这里做个简单介绍:
首先最常用的,也是最效率的方法是根据id去更新,这时候调用的是update方法:
public static function updateEsById($id,$data = [])
{
if (empty($id) || empty($data)){
return false;
}
$es = new Elastic();
$data=[
'index' => self::$es_index,
'type' => self::$es_type,
'id' => $id,
'body' => [
'doc'=> $data //这里的data是个一维关联数组,和常用的ORM更新方法参数一致。
]
];
$res = $es->update($data);
return $res['result'];
}
是不是很简单?
另外还有种情况就是我们不知道需要更新数据的id,或者说我们需要根据条件批量更新,这时候可以用updateByQuery方法:
$params = [
'index' => StatLog::$es_index,
'type' => StatLog::$es_type,
'body' => [
'query' => [
'bool' => [
'must' => [
0=>['term' => [
'uuid' =>'147ee4a81cb94471014ecb21ae74a88f'
]],
1=>['term' => [
'args' =>'http%3A%2F%2Foverhit.wiki.dev.yingxiong.com%2Fcontentmoba%2F2452.html'
]] ,
2=>['term' => [
'add_time' =>1542341128
]]
]
],
],
'script'=>[
//将online_time字段更新为params里传入的值,这里是11111
"inline"=> "ctx._source.online_time=params.online_time",
//这里可以实现某个字段自增等需求,比如:
// "inline"=> "ctx._source.online_time= ctx._source.online_time params.online_time",
'params'=>['online_time'=>11111],
'lang'=>'painless'
]
]
];
$client = new Elastic();
$res = $client->updateByQuery($params);
var_dump($res);
我这里的条件是多个,并且都是=,当然也可以根据range等逻辑运算进行过滤,比如:
$params = [
'index' => 'my_index',
'body' => [
'query' => [
'bool' => [
'must' => [
'range' => [
'age' => [
'gt' => '20',
'lt' => '40'
]
]
]
]
],
'script' => [
'inline' => "ctx._source.name=\"青年人\"; ctx._source.age=30"
]
]
];
$client = Elasticsearch\ClientBuilder::create()->setHosts(['127.0.0.1:9200'])->build();
$res = $client->updateByQuery($params);
简单封装了个PHP的方法:
/**
* Notes :
* @param array $where
* @param string $field
* @param string $value
* @return bool
* author: leojen
* @date: 18-11-21 下午6:06
*/
public static function upByWhere($where = [],$data = [])
{
if (empty($where) || empty($data)){
return false;
}
$fields = '';
foreach ($data as $k=>$v){
$fields .="ctx._source.{$k} = $v;";
}
$fields = trim($fields,';');
$params = [
'index' => self::$es_index,
'type' => self::$es_type,
'body' => [
'query' => [
'bool'=>['must'=>[]]
],
'script'=>[
"inline"=> $fields,
'lang'=>'painless'
]
]
];
foreach ($where as $key=>$val){
$params['body']['query']['bool']['must'][] = [
'term' => [
$key =>$val
]
];
}
$client = new Elastic();
return $client->updateByQuery($params);
}