Исключение для массового обновления Java Elasticsearch

Я пытаюсь массово обновить существующий индекс, используя массовый API, поэтому некоторые записи уже существуют, которые необходимо обновить, а некоторые являются новыми, которые необходимо проиндексировать, поскольку их там нет. Я использовал следующий фрагмент кода

BulkRequestBuilder bulkRequestBuilder = client.prepareBulk();
bulkRequestBuilder.add(client.prepareUpdate(InvokeMain.indexName, type, docId).setUpsert(finalMap));

Однако при этом я получаю следующее исключение

org.elasticsearch.action.ActionRequestValidationException: Validation      
Failed: script or doc is missing;

Я предполагаю, что новые записи / новые идентификаторы документов - это то, где он терпит неудачу. Любая идея, как добиться upsert (обновить, если существует, вставить, если нет) оптом?


person Arnav Sengupta    schedule 01.09.2015    source источник
comment
Вы можете показать, как выглядит finalMap? Можете ли вы вместо этого попробовать prepareIndex?   -  person Val    schedule 01.09.2015
comment
Это карта имени столбца elasticsearch, а значение - это объект, который может быть картой, строкой, списком или чем-то еще. Карта ‹Строка, Объект›. Я использую то же самое для создания индекса, отлично работает. Даже обновление существующих записей работает нормально (изменение приведенного выше фрагмента на setDoc (finalMap) вместо setUpsert.)   -  person Arnav Sengupta    schedule 01.09.2015
comment
Кроме того, prepareIndex я использую для создания индекса, существующие записи не обновляются таким образом. Непостоянное поведение. Некоторые записи меняются, если я даю одинаковый docId при индексировании, некоторые - нет. Кроме того, prepareIndex не предлагает upsert.   -  person Arnav Sengupta    schedule 01.09.2015


Ответы (1)


При использовании upsert (т.е. setUpsert) ваш finalMap должен немного отличаться, так как описано в официальных документах, а именно он должен содержать doc (ваш случай) или script (отсюда ошибка проверки, указывающая, что script или doc отсутствует):

...
Map<String, Object> docMap = ... your current map containing the fields...;
Map<String, Object> finalMap = new HashMap<String, Object>();
finalMap.put("doc", docMap);
...
person Val    schedule 01.09.2015
comment
Как тогда этот же код работает при создании индекса? FinalMap - не что иное, как источник документа. Не все его поля проиндексированы. Когда я создаю индекс с помощью prepareIndex, я использую тот же фрагмент кода, где у меня есть prepareIndex (indexname, type, docId) и finalMap в качестве источника. В finalMap нет самого docId, поскольку он мне не нужен в источнике документа. И это тоже работает для обновления. - person Arnav Sengupta; 01.09.2015
comment
Это работает для обновления: bulkRequestBuilder.add (client.prepareUpdate (InvokeMain.indexName, type, docId) .setDoc (finalMap)). Как тогда? - person Arnav Sengupta; 01.09.2015
comment
Поскольку вы используете setUpsert в приведенном выше коде, все, что я говорю, это то, что вы не можете передать свою карту документа напрямую, но вам нужно передать ее как дополнительную карту в ключ doc. - person Val; 03.09.2015