Kevin S
Kevin S

Reputation: 101

How to append on existing field with elasticsearch python?

I am using kibana and Elasticsearch version 5.1.1 and python version 3.6.

I have created my index like this put_books

The function to add a user is this one :

def add_user(first_name, last_name, age, mail):
    doc = {"first_name": "" + first_name, "last_name": "" + last_name, "age": age, "email": "" + mail}
    global id_user
    res = es.index(index="books", doc_type="user", id=id_user, body=doc)
    id_user += 1
    print(res['result']) 

and to add preferences :

def add_preferences(preferences, i):
    doc = es.get(index="books", doc_type="user", id=id_book)
    res = es.update(index="books", doc_type="user", id=i, body={'doc':{"keyword_preferences": preferences}})

My problem is here : when I want to add preferences, it success but if I want to add again preferences, it replace it :

id_user = 1
nom = "nom_1"
prenom = "prenom_1"
age = 45
email = "adresse_mail_1"
add_user(prenom, nom, age, email)
add_preferences("comique", 1)
add_preferences("horreur", 1)
get_user(1)

the result is :

updated
{'first_name': 'prenom_1', 'last_name': 'nom_1', 'age': 45, 'email': 'adresse_mail_1', 'keyword_preferences': 'horreur'}

Finally, the solution was :

POST /books/user/1/_update
{
  "script" : {
    "inline": "ctx._source.keyword_preferences += params.preference",
    "lang": "painless",
    "params" : {
        "preference" : ["comique"]
    }
  }
}

Upvotes: 5

Views: 7001

Answers (2)

Ashwani Shakya
Ashwani Shakya

Reputation: 439

Edited. example answer for your question.

Index a doc

POST /books/user/1
{
   "keyword_preferences": ["comique"]
}

Now, update a doc to append horreur in keyword_preferences key.

POST /books/user/1/_update
{
    "script": "ctx._source.keyword_preferences += keyword_preferences",
    "params": {
        "keyword_preferences": ["horreur"]
    },
    "lang": "groovy"
}

This will update keyword_preferences as ["comique", "horreur"].

If update API throws as exception {"type":"script_exception","reason":"scripts of type [inline], operation [update] and lang [groovy] are disabled"}, then you need to config elasticsearch.yml. Add script.engine.groovy.inline.update: on script.groovy.sandbox.enabled: true in elasticsearch.yml and restart you elasticsearch. I hope this helps.

Upvotes: 0

Kevin S
Kevin S

Reputation: 101

The new function is :

def add_preferences(preferences, i):
   doc = es.get(index="books", doc_type="user", id=i)
   res = es.update(index="books", doc_type="user", id=i, body={'doc': {'keyword_preferences': [{"preferences": preferences}]}})

The mapping is done and now I've got the result :

{'first_name': 'prenom_1', 'last_name': 'nom_1', 'age': 45, 'email': 'mail_1', 'keyword_preferences': [{'preferences': 'horreur'}]}

So, it has replaced the first preference "comique" by "horreur"

Upvotes: 2

Related Questions