I have a elasticsearch document in the following format. I need to partial update the "x" field and add a python dict in it.
{
"_index": "gdata34",
"_type": "gdat",
"_id": "328091-72341-118",
"_version": 1,
"_score": 1,
"_source": {
"d": {
"Thursday": {
"s": ""
},
"Email": {
"s": ""
},
"Country": {
"s": "US"
},
},
"x": {
"Geo": {
"s": "45.335428,-118.057133",
"g": [
-118.057133
,
45.335428
]
}
},
}
}
I tried the following code to update:
from elasticsearch import Elasticsearch, exceptions
import pprint
elasticsearch = Elasticsearch()
doc = elasticsearch.get(index='gdata34', doc_type='gdat', id='328091-72341-7')
elasticsearch.update(index='gdata34', doc_type='gdat', id='328091-72341-7',
body={"script":"ctx._source.x += y",
"params":{"y":"z"}
}
)
elasticsearch.indices.refresh(index='gdata34')
new_doc = elasticsearch.get(index='gdata34', doc_type='gdat', id='328091-72341-7')
I am getting this error:
elasticsearch.exceptions.RequestError: TransportError(400, u'ElasticsearchIllegalArgumentException[failed to execute script]; nested: ScriptException[dynamic scripting for [groovy] disabled]; ')
What is the right way to do partial update in elasticsearch using python?
For future reference, the following method of partial update worked.
elasticsearch.update(index='gdata34', doc_type='gdat', id='328091-72341-7',
body={
'doc': {'x': {'y':'z'}}
}
)
From the ElasticSearch docs on scripting:
We recommend running Elasticsearch behind an application or proxy, which protects Elasticsearch from the outside world. If users are allowed to run dynamic scripts (even in a search request), then they have the same access to your box as the user that Elasticsearch is running as. For this reason dynamic scripting is allowed only for sandboxed languages by default.
Now, in recent ES version there has been a bug in the vulnerability in the Groovy scripting engine that allows scripts to escape the sandbox and execute shell commands as the user running the Elasticsearch Java VM - that's why the Groovy sandbox is disabled by default in recent versions, and therefore the execution of Groovy scripts passed in the request body or from the .scripts
index. The only way to execute Groovy scripts with this default configuration is to place them in the config/scripts/
directory on the node.
So you have two options:
script.groovy.sandbox.enabled: true
in config/elasticsearch.yml
on your node(s). If your ES instance is accessible by yourconfig/scripts
directory of your node(s), and call it by name. See Running Groovy Scripts without Dynamic Scripting for details.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With