英文:
Python Elasticsearch update with script exception
问题
我正在尝试使用Python的Elasticsearch客户端将新对象附加到文档的数组中(请参见下面的代码片段)。但是我遇到了**RequestError(400, 'illegal_argument_exception', 'failed to execute script')**错误。
Python代码:
def index_doc(doc_id, index):
try:
body = {
"script": {
"source": "ctx._source.array_1.add(params.data)",
"lang": "painless",
"params": {
"data": {
"field1": "abc",
"field2": 3
}
}
}
}
client.update(
index=index,
id=doc_id,
routing=doc_id,
body=body
)
except Exception as e:
print("exception - ", doc_id, e)
尝试使用"script"参数也遇到了相同的**RequestError(400, 'illegal_argument_exception', 'failed to execute script')**错误:
def index_doc(doc_id, index):
try:
script = {
"source": "ctx._source.array_1.add(params.data)",
"lang": "painless",
"params": {
"data": {
"field1": "abc",
"field2": 3
}
}
}
client.update(
index=index,
id=doc_id,
routing=doc_id,
script=script
)
except Exception as e:
print("exception - ", doc_id, e)
我使用Postman命令测试了相同的更新载荷,没有任何问题,新对象可以插入到文档的数组中。请参见curl命令:
curl --location --request POST 'https://<endpoint>/<index_name>/_update/<doc_id>?routing=<doc_id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic <token>' \
--data-raw '{
"script": {
"source": "ctx._source.array_1.add(params.data)",
"lang": "painless",
"params": {
"data": {
"field1": "abc",
"field2": 3
}
}
}'
因此,有人可以分享一下可能的原因吗?我正在使用ES 7.17版本。非常感谢。
英文:
I am trying to use python ES client to append the new object into the array of document (see code snippet below). But I got the RequestError(400, 'illegal_argument_exception', 'failed to execute script')
Python code:
def index_doc(doc_id, index):
try:
body = {
"script": {
"source": "ctx._source.array_1.add(params.data)",
"lang": "painless",
"params": {
"data": {
"field1": "abc",
"field2": 3
}
}
}
}
client.update(
index=index,
id=doc_id,
routing=doc_id,
body=body
)
except Exception as e:
print("exception - ", doc_id, e)
Tried "script" parameter too, got same RequestError(400, 'illegal_argument_exception', 'failed to execute script'):
def index_doc(doc_id, index):
try:
script = {
"source": "ctx._source.array_1.add(params.data)",
"lang": "painless",
"params": {
"data": {
"field1": "abc",
"field2": 3
}
}
}
client.update(
index=index,
id=doc_id,
routing=doc_id,
script=script
)
except Exception as e:
print("exception - ", doc_id, e)
I tested the same update payload with postman command, there is no any problem, the new object can be inserted into the array of document. See curl command:
curl --location --request POST 'https://<endpoint>/<index_name>/_update/<doc_id>?routing=<doc_id>' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic <token>' \
--data-raw '{
"script": {
"source": "ctx._source.array_1.add(params.data)",
"lang": "painless",
"params": {
"data": {
"field1": "abc",
"field2": 3
}
}
}
}'
So, could anyone share thoughts what might be the culprit? I am using ES 7.17. Thanks much in advance.
Update the trackback log here:
client.update(
exception - <doc_id> RequestError(400, 'illegal_argument_exception', 'failed to execute script')
Traceback (most recent call last):
File "/<file_path>", line 137, in index_doc
client.update(
File "/Library/Python/3.9/site-packages/elasticsearch/client/utils.py", line 347, in _wrapped
return func(*args, params=params, headers=headers, **kwargs)
File "/Library/Python/3.9/site-packages/elasticsearch/client/__init__.py", line 2092, in update
return self.transport.perform_request(
File "/Library/Python/3.9/site-packages/elasticsearch/transport.py", line 466, in perform_request
raise e
File "/Library/Python/3.9/site-packages/elasticsearch/transport.py", line 427, in perform_request
status, headers_response, data = connection.perform_request(
File "/Library/Python/3.9/site-packages/elasticsearch/connection/http_urllib3.py", line 291, in perform_request
self._raise_error(response.status, raw_data)
File "/Library/Python/3.9/site-packages/elasticsearch/connection/base.py", line 328, in _raise_error
raise HTTP_EXCEPTIONS.get(status_code, TransportError)(
elasticsearch.exceptions.RequestError: RequestError(400, 'illegal_argument_exception', 'failed to execute script')
答案1
得分: 0
根据官方文档(8.x),您不需要指定body
,而是直接使用脚本:
client.update(
index=index,
id=doc_id,
routing=doc_id,
script=script <------
)
英文:
Per the official documentation (8.x), you don't specify a body
but the script directly:
client.update(
index=index,
id=doc_id,
routing=doc_id,
script=script <------
)
答案2
得分: 0
已找到问题。
文档中的数组一开始不存在,所以如果我直接将对象添加到数组中,就会出现问题。当我昨天尝试curl命令时,文档ID不同,所以curl没有触发错误。因此,我添加了以下的空值检查,问题得以解决。
还要感谢@Val分享他的知识。
"source" : "if (ctx._source.array_1 == null) { ctx._source.array_1 = [params.data]; } else {ctx._source.array_1.add(params.data)}"
英文:
Figured out the issue.
The array in the doc does not exists at the beginning, so if I directly add object into the array, it will have the error mentioned in the question. When I tried the curl command yesterday, the doc id is different, so the curl didn't trigger the error. So, I added the null checks like below, then the issue is resolved.
Also, thanks @Val for sharing his knowledge.
"source" : "if (ctx._source.array_1 == null) { ctx._source.array_1 = [params.data]; } else {ctx._source.array_1.add(params.data)} "
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论