我有一个候选索引,其中文档的结构如下:
{
"_index" : "candidates",
"_type" : "_doc",
"_id" : "a23OcncBXBMGOH6pwXge",
"_version" : 1,
"_seq_no" : 1,
"_primary_term" : 1,
"found" : true,
"_source" : {
"id" : "413",
"firstname" : "Tania",
"lastname" : "Stroman",
"email" : "Berlin@yahoo.com",
"zip" : "60306",
"city" : "frankfurt",
"birthday" : "1978-11-22",
"tags" : [
"php",
"munich"
],
"location" : {
"lat" : 50.11601257324219,
"lon" : 8.669955253601074
}
}
}
一旦候选人上传了他们的文件,如果它是第一个上传的文件,我会在弹性文档中添加一个名为“文件”的字段。如果文档中已经有上传的文件,我使用以下代码将后续上传的文件推送到现有数组:
public function attachCandidateFile($file)
{
$client = ClientBuilder::create()->build();
$params = [
'index' => 'candidates',
'id' => $file['candidate_id']
];
$candidate = $client->get($params);
if (!is_array($candidate['_source']['file'])) {
$candidate['_source']['file'] = [];
}
array_push($candidate['_source']['file'], $file);
$params = [
'index' => 'candidates',
'type' => '_doc',
'id' => $file['candidate_id'],
'body' => [
'doc' => [
'file' => $candidate['_source']['file']
]
]
];
$response = $client->update($params);
echo '<pre>', print_r($response, true) ,'</pre>';
}
有没有办法直接用新对象更新候选人的文件而不需要获取 $candidate['_source']['file']
以避免覆盖它?
答案 0 :(得分:0)
当然——当您知道要更新哪个文档时使用 update script(使用其 _id
):
POST candidates/_update/a23OcncBXBMGOH6pwXge
{
"script": {
"source": """
if (ctx._source.containsKey('file')) {
ctx._source.file.add(['filename':params.filename]); // adding a hash map -- could be any JSON primitive
} else {
ctx._source.file = [['filename':params.filename]]; // 1-member array
}
""",
"params": {
"filename": "abc"
}
}
}
或者,使用与上述相同的脚本,但在 _update_by_query
call 下。您可以定位该文档(甚至可能是多个文档)无需获取它们。