"конфликт версий, текущая версия отличается от предоставленной" при запуске update_by_query curl в сценарии php
Я должен обновить некоторые поля в моих документах ES.
У меня есть промежуточное поле 'objectID', которое является уникальным идентификатором объекта, рассматриваемого в документе.
У меня есть поле String 'objectType', которое является типом объекта, затрагиваемого документом.
Все документы описывают действие над объектом, а objectType и objecID всегда присутствуют во всех документах.
К сожалению, некоторые документы с objectType "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". Я знаю, что могу передать параметры в сценарий, но я не знаю, могу ли я или как использовать результат запроса в этом.
Спасибо!
РЕДАКТИРОВАТЬ:
Я решил часть своей проблемы, извлекая csv-список соответствующих objectID с помощью необработанного экспорта Kibana, и я создал PHP-скрипт для анализа каждого objectID и поместил его в строку запроса для моего update_by_query, который просто находит ВСЕ документ с совпадающим objectID и замените значение поля objectType на "post_image".
Я использую php curl, чтобы сделать этот вызов, и у меня есть проблемы с конфликтом версий, несмотря на использование "конфликтов": "продолжить" в моем запросе. Я протестировал тот же самый запрос в консоли разработчика в 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}
Это довольно странно, так как я не даю никакой версии документа в моем запросе. Возможно, это связано с каким-то автоматическим внутренним поведением из API upbade_by_query.
1 ответ
Я исправил все мысли окончательно.
Прежде всего, я немного переработал свой запрос:
$query = "{ \"query\": {
\"bool\": {
\"must\": {
\"match\": {
\"objectType\": \"Post\" <- more optimal!
}
},
\"filter\": {
\"term\": {
\"objectID\":
\"".$id."\"
}
}
}
},
\"script\": {
\"lang\": \"painless\",
\"source\": \"ctx._source['content'] = '".$argv[2]."'\"
}
}";
argv [2] - это objectType, который я хочу передать своим документам. ("Post_image")
Затем мне пришлось удалить JSON_encode($query) в строке перед curl_exec
curl_setopt($conn, CURLOPT_POSTFIELDS, $query);
$response = curl_exec($conn);
Затем я перестал иметь ошибку, НО у меня было много пустых результатов, что было странно, потому что запрос возвращал результаты при использовании инструментов разработчика kibana, но потом я понял, что использовал неправильный IP-адрес и отправлял все на другой, и запускал тестовую ES, которая имела тот же индекс / типы, но без каких-либо фактических документов в индексе, следовательно, пустые результаты без реальных ошибок. Я чувствовал себя немного глупым.
PS: ЗАПРОС ОСОБЕННОСТИ: смайлик лицевой стороны.