"конфликт версий, текущая версия отличается от предоставленной" при запуске 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: ЗАПРОС ОСОБЕННОСТИ: смайлик лицевой стороны.

Другие вопросы по тегам