Append to an existing field in java api

Здравствуйте, у меня такая задача. Мне нужно расширить существующее поле в индексе новыми значениями, то есть новые и старые должны остаться в индексе.
Тут я нашла пример:
curl -XPOST "http://localhost:9200/t/t/1/_update" -d'
{
"script" : "ctx._source.hobbies += hobby",
"params" : {
"hobbies" : ["d", "e"]
}
}'
Я пытаюсь сделать это в java. И у меня не получается передать параметры в prepareUpdate(), а пример я не смогла найти.
Итак, я создаю params:
Map<String,Object> params = new HashMap<>();
List hobbies = new ArrayList<>();
hobbies.add("d");
hobbies.add("e")
params. put("hobbies", hobbies);
Итак, здесь у меня не получается передать параметры в мою update query. Я видела примеры с .addScriptParam(), но такой метод у меня не существует. Я использую es 5.0.0.
Вот что у меня на данный момент:
client.prepareUpdate("t", "t", "1").setScript(new Script("ctx._source.hobbies += hobbi")).execute().actionGet();
Буду очень рада помощи, так как сегодня целый день с этим разбираюсь.

В java нужно использовать другой конструктор. Выглядить это будет как-то так:

client.prepareUpdate("t", "t", "1").setScript(
     new Script(ScriptType.INLINE, "painless", "ctx._source.hobbies += hobbi", params))
  .execute().actionGet();

Спасибо! Работает, только нужно было поменять параметры местами. То есть вот так:

client.prepareUpdate("t", "t", "1").setScript(
new Script( "painless", ScriptService.ScriptType.INLINE,"ctx._source.hobbies += hobbi", params))
.execute().actionGet();

В другом порядке компилятор ругается, не пойму почему.

Теперь у меня другая проблема.

Caused by: java.lang.IllegalArgumentException: script_lang not supported [ctx._source.hobbies += hobbies]

В elasticsearch.yaml я поставила такие данные:
script.inline: true
script.update: true
В интернете находила решения для groovy, но "painless" уже встроен, как я поняла.
Спасибо!
И еще, как Вы делаете, что код отображается по-особому.

В log у меня стоит no plugins loaded, то есть у меня module [lang-painless] не установлен. Никак не могу найти, как его установить.

Да, я по ошибке пример из 5.1 привел. В 5.0 другой конструктор был, и пример для 5.0 будет выглядить как-то так:

client.prepareUpdate("t", "t", "1").setScript(
   new Script( "ctx._source.hobbies += hobbi", ScriptService.ScriptType.INLINE, "painless", params))
.execute().actionGet();

Спасибо. А по этой ошибке Вы не можете подсказать:
Caused by: java.lang.IllegalArgumentException: script_lang not supported [ctx._source.hobbies += hobbies]. Или нужно новый вопрос задать.

В вашем примере или в последнем моем?

В моем примере. То есть такой код:
client.prepareUpdate("t", "t", "1").setScript(
new Script( "painless", ScriptService.ScriptType.INLINE,"ctx._source.hobbies += hobbies", params))
.execute().actionGet();
Всё запускается, только потом появляется ошибка:

Caused by: java.lang.IllegalArgumentException: script_lang not supported [ctx._source.hobbies += hobbies]

Я посмотрела в логе, там написано, что no plugins loaded. То есть module [lang-painless] тоже не загрузился. Поэтому и вылезает эта ошибка script_lang not supported.

Я в растерянности, так как в интернете советуют включить модуль lang-painless from org.elasticsearch.module. Здесь написано: https://github.com/elastic/elasticsearch/issues/11620. Но я не очень понимаю, как это сделать. И у меня все-таки es5.1.

В вашем примере имя языка (параметр lang) и сам скрипт (параметр script) перепутаны местами.

Я попробовала Ваш пример, появляется уже другая ошибка. Сейчас поищу решение.

Какая ошибка?

Caused by: java.lang.IllegalArgumentException: Variable [hobbies] is not defined. Хотя у меня добавлено:

Map<String, Object> params = new Hashmap<>();
List hobbies = new ArrayList();
hobbies.add("a");
params.put("hobbies", hobbies);

А если так попробовать?

"ctx._source.hobbies += params.hobbi"

Нет, все-таки не работает.

Caused by: NotSerializableExceptionWrapper[class_cast_exception: Cannot apply [+] operation to types [java.util.ArrayList] and [java.util.ArrayList].]

Может попробовать addAll вместо +

Ошибка для client.prepareUpdate("t", "t", "1")).setScript(new Script("ctx._source.hobbies.addAll(params.hobbies)", ScriptService.ScriptType.INLINE, "painless", params)).execute().actionGet();

Caused by: java.lang.IllegalArgumentException: Unable to find dynamic method [addAll] with [1] arguments for class [java.lang.String].

Всё работает, нужно просто было удалить документы, на которых я тестила, и запустить заново. Спасибо огромное за терпение!

Итог, нужно

  1. применять правильный конструктор для скрипта. Взависимости от версии конструкторы разные.
  2. удалить тестовые данные после запуска, если вылезает ошибка, так как создается неправильный mapping.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.