Здравствуйте, у меня такая задача. Мне нужно расширить существующее поле в индексе новыми значениями, то есть новые и старые должны остаться в индексе.
Тут я нашла пример:
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].
Всё работает, нужно просто было удалить документы, на которых я тестила, и запустить заново. Спасибо огромное за терпение!
Итог, нужно
- применять правильный конструктор для скрипта. Взависимости от версии конструкторы разные.
- удалить тестовые данные после запуска, если вылезает ошибка, так как создается неправильный mapping.
This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.