5

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"]
    }
  }
}
Kevin S
  • 101
  • 1
  • 7
  • what is your expected result? – Ashwani Shakya Jul 09 '18 at 09:03
  • My expected result is : updated{'first_name': 'prenom_1', 'last_name': 'nom_1', 'age': 45, 'email': 'adresse_mail_1', 'keyword_preferences': {'comique', 'horreur'}} – Kevin S Jul 09 '18 at 09:07
  • You can't save keyword_preferences like above. You may save data in the list of dictionaries like `{ 'keyword_preferences': [{"preferences": "comique"},{"preferences": "horreur"}]}`. For more info follow this [link](https://www.elastic.co/guide/en/elasticsearch/reference/5.1/array.html) . – Ashwani Shakya Jul 09 '18 at 09:22
  • I tried res = es.update(index="books", doc_type="user", id=i, body={'doc': {'keyword_preferences': [{"preferences" : preferences}]}}) but I have now : TransportError(400, 'mapper_parsing_exception', 'failed to parse [keyword_preferences]' And when I modify the mapping it doesn't change – Kevin S Jul 09 '18 at 12:18
  • First, you need to create the mapping for `keyword_preferrences`. then index into it. – Ashwani Shakya Jul 09 '18 at 12:38

2 Answers2

2

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"

Kevin S
  • 101
  • 1
  • 7
0

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.

Ashwani Shakya
  • 419
  • 4
  • 11