# Append to an existing field in java api

**URL:** <https://discuss.elastic.co/t/append-to-an-existing-field-in-java-api/72644>\
**Category:** Вопросы на русском языке\
**Created:** [January 24, 2017, 2:29pm UTC](https://discuss.elastic.co/t/append-to-an-existing-field-in-java-api/72644 "2017-01-24T14:29:01Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![Katja](https://avatars.discourse-cdn.com/v4/letter/k/0ea827/32.png) [@Katja](https://discuss.elastic.co/u/Katja)\
**Post date:** [January 24, 2017, 2:29pm UTC](https://discuss.elastic.co/t/append-to-an-existing-field-in-java-api/72644/1 "2017-01-24T14:29:01Z")

</div>

Здравствуйте, у меня такая задача. Мне нужно расширить существующее поле в индексе новыми значениями, то есть новые и старые должны остаться в индексе.  
Тут я нашла пример:  
curl -XPOST "[http://localhost:9200/t/t/1/\_update](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();  
Буду очень рада помощи, так как сегодня целый день с этим разбираюсь.

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [January 24, 2017, 3:14pm UTC](https://discuss.elastic.co/t/append-to-an-existing-field-in-java-api/72644/2 "2017-01-24T15:14:58Z")

</div>

В java нужно использовать другой [конструктор](https://github.com/elastic/elasticsearch/blob/5.1/core/src/main/java/org/elasticsearch/script/Script.java#L347). Выглядить это будет как-то так:

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

```

---

<div class="post-metadata">

**Author:** ![Katja](https://avatars.discourse-cdn.com/v4/letter/k/0ea827/32.png) [@Katja](https://discuss.elastic.co/u/Katja)\
**Post date:** [January 25, 2017, 8:06am UTC](https://discuss.elastic.co/t/append-to-an-existing-field-in-java-api/72644/3 "2017-01-25T08:06:52Z")

</div>

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

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" уже встроен, как я поняла.  
Спасибо!  
И еще, как Вы делаете, что код отображается по-особому.

---

<div class="post-metadata">

**Author:** ![Katja](https://avatars.discourse-cdn.com/v4/letter/k/0ea827/32.png) [@Katja](https://discuss.elastic.co/u/Katja)\
**Post date:** [January 25, 2017, 9:16am UTC](https://discuss.elastic.co/t/append-to-an-existing-field-in-java-api/72644/4 "2017-01-25T09:16:42Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [January 25, 2017, 1:39pm UTC](https://discuss.elastic.co/t/append-to-an-existing-field-in-java-api/72644/5 "2017-01-25T13:39:31Z")

</div>

Да, я по ошибке пример из 5.1 привел. В 5.0 другой [конструктор](https://github.com/elastic/elasticsearch/blob/5.0/core/src/main/java/org/elasticsearch/script/Script.java#L63) был, и пример для 5.0 будет выглядить как-то так:

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

```

---

<div class="post-metadata">

**Author:** ![Katja](https://avatars.discourse-cdn.com/v4/letter/k/0ea827/32.png) [@Katja](https://discuss.elastic.co/u/Katja)\
**Post date:** [January 25, 2017, 1:53pm UTC](https://discuss.elastic.co/t/append-to-an-existing-field-in-java-api/72644/6 "2017-01-25T13:53:18Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [January 25, 2017, 1:55pm UTC](https://discuss.elastic.co/t/append-to-an-existing-field-in-java-api/72644/7 "2017-01-25T13:55:21Z")

</div>

> [@Katja](#):
>
> Спасибо. А по этой ошибке Вы не можете подсказать:Caused by: java.lang.IllegalArgumentException: script\_lang not supported [ctx.\_source.hobbies += hobbi].

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

---

<div class="post-metadata">

**Author:** ![Katja](https://avatars.discourse-cdn.com/v4/letter/k/0ea827/32.png) [@Katja](https://discuss.elastic.co/u/Katja)\
**Post date:** [January 25, 2017, 2:02pm UTC](https://discuss.elastic.co/t/append-to-an-existing-field-in-java-api/72644/8 "2017-01-25T14:02:52Z")

</div>

В моем примере. То есть такой код:  
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](https://github.com/elastic/elasticsearch/issues/11620). Но я не очень понимаю, как это сделать. И у меня все-таки es5.1.

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [January 25, 2017, 2:12pm UTC](https://discuss.elastic.co/t/append-to-an-existing-field-in-java-api/72644/9 "2017-01-25T14:12:35Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Katja](https://avatars.discourse-cdn.com/v4/letter/k/0ea827/32.png) [@Katja](https://discuss.elastic.co/u/Katja)\
**Post date:** [January 25, 2017, 2:16pm UTC](https://discuss.elastic.co/t/append-to-an-existing-field-in-java-api/72644/10 "2017-01-25T14:16:54Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [January 25, 2017, 2:17pm UTC](https://discuss.elastic.co/t/append-to-an-existing-field-in-java-api/72644/11 "2017-01-25T14:17:32Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Katja](https://avatars.discourse-cdn.com/v4/letter/k/0ea827/32.png) [@Katja](https://discuss.elastic.co/u/Katja)\
**Post date:** [January 25, 2017, 2:19pm UTC](https://discuss.elastic.co/t/append-to-an-existing-field-in-java-api/72644/12 "2017-01-25T14:19:28Z")

</div>

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);

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [January 25, 2017, 2:20pm UTC](https://discuss.elastic.co/t/append-to-an-existing-field-in-java-api/72644/13 "2017-01-25T14:20:18Z")

</div>

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

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

---

<div class="post-metadata">

**Author:** ![Katja](https://avatars.discourse-cdn.com/v4/letter/k/0ea827/32.png) [@Katja](https://discuss.elastic.co/u/Katja)\
**Post date:** [January 25, 2017, 2:25pm UTC](https://discuss.elastic.co/t/append-to-an-existing-field-in-java-api/72644/14 "2017-01-25T14:25:35Z")

</div>

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

Caused by: NotSerializableExceptionWrapper[class\_cast\_exception: Cannot apply [+] operation to types [java.util.ArrayList] and [java.util.ArrayList].]

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [January 25, 2017, 2:31pm UTC](https://discuss.elastic.co/t/append-to-an-existing-field-in-java-api/72644/15 "2017-01-25T14:31:49Z")

</div>

Может попробовать [`addAll`](https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#addAll(java.util.Collection)) вместо `+`

---

<div class="post-metadata">

**Author:** ![Katja](https://avatars.discourse-cdn.com/v4/letter/k/0ea827/32.png) [@Katja](https://discuss.elastic.co/u/Katja)\
**Post date:** [January 25, 2017, 2:39pm UTC](https://discuss.elastic.co/t/append-to-an-existing-field-in-java-api/72644/16 "2017-01-25T14:39:40Z")

</div>

Ошибка для 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].

---

<div class="post-metadata">

**Author:** ![Katja](https://avatars.discourse-cdn.com/v4/letter/k/0ea827/32.png) [@Katja](https://discuss.elastic.co/u/Katja)\
**Post date:** [January 25, 2017, 2:54pm UTC](https://discuss.elastic.co/t/append-to-an-existing-field-in-java-api/72644/17 "2017-01-25T14:54:27Z")

</div>

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

Итог, нужно

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

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [February 22, 2017, 2:55pm UTC](https://discuss.elastic.co/t/append-to-an-existing-field-in-java-api/72644/18 "2017-02-22T14:55:08Z")

</div>

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