我有以下格式的弹性搜索文档。我需要部分更新“x”字段并在其中添加python dict。
{
"_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
]
}
},
}
}
我尝试了以下代码进行更新:
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')
我收到此错误:
elasticsearch.exceptions.RequestError: TransportError(400, u'ElasticsearchIllegalArgumentException[failed to execute script]; nested: ScriptException[dynamic scripting for [groovy] disabled]; ')
使用python在elasticsearch中进行部分更新的正确方法是什么?
答案 0 :(得分:12)
为了将来参考,以下部分更新方法有效。
elasticsearch.update(index='gdata34', doc_type='gdat', id='328091-72341-7',
body={
'doc': {'x': {'y':'z'}}
}
)
答案 1 :(得分:1)
来自ElasticSearch docs on scripting:
我们建议在应用程序或代理后面运行Elasticsearch, 它保护Elasticsearch免受外界影响。如果用户是 允许运行动态脚本(即使在搜索请求中),然后是它们 与Elasticsearch所用的用户具有相同的访问权限 跑来跑去。 因此,仅允许动态脚本 默认情况下使用沙盒语言。
现在,在最近的ES版本中,Groovy脚本引擎中的漏洞存在一个漏洞,它允许脚本在运行Elasticsearch Java VM时逃离沙箱并执行shell命令 - 这就是{的原因{ {3}},因此执行在请求正文或.scripts
索引中传递的Groovy脚本。使用此默认配置执行Groovy脚本的唯一方法是将它们放在节点上的config/scripts/
目录中。
所以你有两个选择:
script.groovy.sandbox.enabled: true
中设置config/elasticsearch.yml
来再次打开Groovy沙盒(s )。如果您的ES实例可以通过config/scripts
目录中的文件系统上,并按名称调用它。有关详细信息,请参阅Groovy sandbox is disabled by default in recent versions。