在 php 脚本中 运行 update_by_query curl 时出现“版本冲突,当前版本与提供的版本不同”
" version conflict, current version is different than the one provided" when running update_by_query curl in php script
我必须更新我的 ES 文档中的一些字段。
我有一个整数'objectID'字段,它是文档关注的对象的唯一id。
我有一个String'objectType'字段,是文档关注的对象类型
所有文档都描述了对对象的操作,并且 objectType 和 objecID 始终存在于所有文档中。
不幸的是,某些对象类型为 "post_image" 的文档已被索引为 "post"。 objectID 仍然是唯一且有效的,并且只有一种类型的文档具有错误的 objectType。因此,所有对象都至少有另一个具有正确 objectType 和相同唯一 objectID 的文档。
我想使用 update_by_query 将 objectType 的值更新为 "post_image" 在 objectType 为 "post" 且 objectID 位于任何其他文档中的所有文档中objectType 是 "post_image".
这是我的伪代码脚本:
{
"query": {
"match" : { "objectType" : "post" } //all documents with objectType post
},
"script": {
"lang": "painless",
"source": "
//subquery selecting all objectIDs from documents with objectType "post_image"
subQueryResults = "query": {
"match" : { "objectType" : "post_image" }
//I don't know to filter results to retrive objectID field only
//no need for help here, i'll figure it out myself
}
if (/*ctx.source['objectID'] in subQueryResults*/){
ctx._source['objectType'] = "post_image"
}
"
}
我是无痛脚本的新手,我不知道如何在我的脚本中放入另一个查询来获取所有 "post_image" id 的列表。我知道我可以将参数传递给脚本,但我也不知道是否或如何在其中使用查询结果。
谢谢!
编辑:
我通过使用 Kibana 原始导出提取相关 objectID 的 csv 列表解决了我的部分问题,并且我制作了一个 PHP 脚本来解析每个 objectID 并将其放入我的查询字符串中update_by_query 简单地找到具有匹配 objectID 的所有文档并将 objectType 字段值替换为 "post_image".
我正在使用 php curl 进行这些调用,尽管在我的请求中使用了 "conflicts" : "proceed",但我还是遇到了版本冲突问题。我已经在 kibana 的开发控制台中测试了完全相同的查询,它工作得很好,我找不到任何解释为什么当 运行 来自 php 时它不更新我的文档。
这是脚本:
<?php
$query = "";
$csvFile = file($argv[1]);
try{
//$data = array();
$query = "";
$i = 0;
$csv_headers = array();
$uri = "http://ip/index/type/_update_by_query";
$conn = curl_init();
curl_setopt($conn, CURLOPT_URL, $uri);
curl_setopt($conn, CURLOPT_TIMEOUT, 5);
curl_setopt($conn, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($conn, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($conn, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($conn, CURLOPT_FAILONERROR, FALSE);
curl_setopt($conn, CURLOPT_CUSTOMREQUEST, strtoupper('POST'));
curl_setopt($conn, CURLOPT_FORBID_REUSE, 0);
foreach ($csvFile as $line) {
try{
//WARNING: separator parameter of str_getcsv call is a risk or error based on the type of CSV used.
//skip header in CSV
if ($i > 0){
$data = str_getcsv($line,',');
//$data = explode(",", $line);
$id = $data[0];
echo $id.", ";
//old query, wasn't working
// $query = "{
// \"conflicts\": \"proceed\",
// \"query\": {
// \"match\" : { \"objectID\" : ".$id."
// }
// },
// \"script\": {
// \"lang\": \"painless\",
// \"source\": \"ctx._source['objectType'] = '".$argv[2]."'\"
// }
// }";
$query = "{
\"conflicts\": \"proceed\",
\"query\": {
\"bool\": {
\"must\": {
\"match\": {
\"objectType\": \"Post\"
}
},
\"filter\": {
\"terms\": {
\"objectID\": [
".$id."
]
}
}
}
},
\"script\": {
\"lang\": \"painless\",
\"source\": \"ctx._source['objectType'] = 'Post_image'\"
}
}";
curl_setopt($conn, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($query))
);
curl_setopt($conn, CURLOPT_POSTFIELDS, json_encode($query));
$response = curl_exec($conn);
//sleep(1);
echo $response;
}
$i++;
}catch(Exception $e){
echo $e->getMessage();
//continue;
}
}catch(Exception $e){
echo $e->getMessage();
}
}
echo $query;
echo "\nCompleted.\n\n";
?>
示例响应:
{"index":"index",
"type":"type",
"id":"AWB0YFcjAFB9uQAwMSKx",
"cause":{"type":"version_conflict_engine_exception",
"reason":"[type][AWB0YFcjAFB9uQAwMSKx]: version conflict,
current version [27] is different than the one provided [26]",
"index_uuid":"yOD9SBy0RMmDZGK_N5o8qw",
"shard":"2",
"index":"index"},
"status":409}
这很奇怪,因为我没有在我的请求中提供任何文档版本。可能它与 upbade_by_query API.
的一些自动内部行为有关
我终于解决了整个想法。
首先,我稍微修改了查询:
$query = "{ \"query\": {
\"bool\": {
\"must\": {
\"match\": {
\"objectType\": \"Post\" <- more optimal!
}
},
\"filter\": {
\"term\": {
\"objectID\":
\"".$id."\"
}
}
}
},
\"script\": {
\"lang\": \"painless\",
\"source\": \"ctx._source['content'] = '".$argv[2]."'\"
}
}";
argv[2] 是我要给我的文档的对象类型。 ("Post_image")
然后,我不得不删除 curl_exec
之前行中的 JSON_encode($query)
curl_setopt($conn, CURLOPT_POSTFIELDS, $query);
$response = curl_exec($conn);
然后我不再有错误但是我有很多空结果这很奇怪因为查询在使用 kibana 开发工具时返回结果但后来我意识到我使用了错误的 IP 并将所有内容发送到另一个 运行 测试具有相同 index/types 但索引中没有任何实际文档的 ES,因此没有实际错误的空结果。我觉得有点傻。
PS:功能请求:表情符号。
我必须更新我的 ES 文档中的一些字段。
我有一个整数'objectID'字段,它是文档关注的对象的唯一id。
我有一个String'objectType'字段,是文档关注的对象类型
所有文档都描述了对对象的操作,并且 objectType 和 objecID 始终存在于所有文档中。
不幸的是,某些对象类型为 "post_image" 的文档已被索引为 "post"。 objectID 仍然是唯一且有效的,并且只有一种类型的文档具有错误的 objectType。因此,所有对象都至少有另一个具有正确 objectType 和相同唯一 objectID 的文档。
我想使用 update_by_query 将 objectType 的值更新为 "post_image" 在 objectType 为 "post" 且 objectID 位于任何其他文档中的所有文档中objectType 是 "post_image".
这是我的伪代码脚本:
{
"query": {
"match" : { "objectType" : "post" } //all documents with objectType post
},
"script": {
"lang": "painless",
"source": "
//subquery selecting all objectIDs from documents with objectType "post_image"
subQueryResults = "query": {
"match" : { "objectType" : "post_image" }
//I don't know to filter results to retrive objectID field only
//no need for help here, i'll figure it out myself
}
if (/*ctx.source['objectID'] in subQueryResults*/){
ctx._source['objectType'] = "post_image"
}
"
}
我是无痛脚本的新手,我不知道如何在我的脚本中放入另一个查询来获取所有 "post_image" id 的列表。我知道我可以将参数传递给脚本,但我也不知道是否或如何在其中使用查询结果。
谢谢!
编辑:
我通过使用 Kibana 原始导出提取相关 objectID 的 csv 列表解决了我的部分问题,并且我制作了一个 PHP 脚本来解析每个 objectID 并将其放入我的查询字符串中update_by_query 简单地找到具有匹配 objectID 的所有文档并将 objectType 字段值替换为 "post_image".
我正在使用 php curl 进行这些调用,尽管在我的请求中使用了 "conflicts" : "proceed",但我还是遇到了版本冲突问题。我已经在 kibana 的开发控制台中测试了完全相同的查询,它工作得很好,我找不到任何解释为什么当 运行 来自 php 时它不更新我的文档。
这是脚本:
<?php
$query = "";
$csvFile = file($argv[1]);
try{
//$data = array();
$query = "";
$i = 0;
$csv_headers = array();
$uri = "http://ip/index/type/_update_by_query";
$conn = curl_init();
curl_setopt($conn, CURLOPT_URL, $uri);
curl_setopt($conn, CURLOPT_TIMEOUT, 5);
curl_setopt($conn, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($conn, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($conn, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($conn, CURLOPT_FAILONERROR, FALSE);
curl_setopt($conn, CURLOPT_CUSTOMREQUEST, strtoupper('POST'));
curl_setopt($conn, CURLOPT_FORBID_REUSE, 0);
foreach ($csvFile as $line) {
try{
//WARNING: separator parameter of str_getcsv call is a risk or error based on the type of CSV used.
//skip header in CSV
if ($i > 0){
$data = str_getcsv($line,',');
//$data = explode(",", $line);
$id = $data[0];
echo $id.", ";
//old query, wasn't working
// $query = "{
// \"conflicts\": \"proceed\",
// \"query\": {
// \"match\" : { \"objectID\" : ".$id."
// }
// },
// \"script\": {
// \"lang\": \"painless\",
// \"source\": \"ctx._source['objectType'] = '".$argv[2]."'\"
// }
// }";
$query = "{
\"conflicts\": \"proceed\",
\"query\": {
\"bool\": {
\"must\": {
\"match\": {
\"objectType\": \"Post\"
}
},
\"filter\": {
\"terms\": {
\"objectID\": [
".$id."
]
}
}
}
},
\"script\": {
\"lang\": \"painless\",
\"source\": \"ctx._source['objectType'] = 'Post_image'\"
}
}";
curl_setopt($conn, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($query))
);
curl_setopt($conn, CURLOPT_POSTFIELDS, json_encode($query));
$response = curl_exec($conn);
//sleep(1);
echo $response;
}
$i++;
}catch(Exception $e){
echo $e->getMessage();
//continue;
}
}catch(Exception $e){
echo $e->getMessage();
}
}
echo $query;
echo "\nCompleted.\n\n";
?>
示例响应:
{"index":"index",
"type":"type",
"id":"AWB0YFcjAFB9uQAwMSKx",
"cause":{"type":"version_conflict_engine_exception",
"reason":"[type][AWB0YFcjAFB9uQAwMSKx]: version conflict,
current version [27] is different than the one provided [26]",
"index_uuid":"yOD9SBy0RMmDZGK_N5o8qw",
"shard":"2",
"index":"index"},
"status":409}
这很奇怪,因为我没有在我的请求中提供任何文档版本。可能它与 upbade_by_query API.
的一些自动内部行为有关我终于解决了整个想法。
首先,我稍微修改了查询:
$query = "{ \"query\": {
\"bool\": {
\"must\": {
\"match\": {
\"objectType\": \"Post\" <- more optimal!
}
},
\"filter\": {
\"term\": {
\"objectID\":
\"".$id."\"
}
}
}
},
\"script\": {
\"lang\": \"painless\",
\"source\": \"ctx._source['content'] = '".$argv[2]."'\"
}
}";
argv[2] 是我要给我的文档的对象类型。 ("Post_image")
然后,我不得不删除 curl_exec
之前行中的 JSON_encode($query)curl_setopt($conn, CURLOPT_POSTFIELDS, $query);
$response = curl_exec($conn);
然后我不再有错误但是我有很多空结果这很奇怪因为查询在使用 kibana 开发工具时返回结果但后来我意识到我使用了错误的 IP 并将所有内容发送到另一个 运行 测试具有相同 index/types 但索引中没有任何实际文档的 ES,因此没有实际错误的空结果。我觉得有点傻。
PS:功能请求:表情符号。