Python Elasticsearch update with script exception

huangapple go评论77阅读模式
英文:

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 = {
            &quot;script&quot;: {
                &quot;source&quot;: &quot;ctx._source.array_1.add(params.data)&quot;,
                &quot;lang&quot;: &quot;painless&quot;,
                &quot;params&quot;: {
                    &quot;data&quot;: {
                        &quot;field1&quot;: &quot;abc&quot;,
                        &quot;field2&quot;: 3
                    }
                }
            }
        }

        client.update(
            index=index,
            id=doc_id,
            routing=doc_id,
            body=body
        )
    except Exception as e:
        print(&quot;exception - &quot;, 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 = {
            &quot;source&quot;: &quot;ctx._source.array_1.add(params.data)&quot;,
            &quot;lang&quot;: &quot;painless&quot;,
            &quot;params&quot;: {
                &quot;data&quot;: {
                    &quot;field1&quot;: &quot;abc&quot;,
                    &quot;field2&quot;: 3
                }
            }
        }

        client.update(
            index=index,
            id=doc_id,
            routing=doc_id,
            script=script
        )
    except Exception as e:
        print(&quot;exception - &quot;, 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 &#39;https://&lt;endpoint&gt;/&lt;index_name&gt;/_update/&lt;doc_id&gt;?routing=&lt;doc_id&gt;&#39; \
--header &#39;Content-Type: application/json&#39; \
--header &#39;Authorization: Basic &lt;token&gt;&#39; \
--data-raw &#39;{
    &quot;script&quot;: {
        &quot;source&quot;: &quot;ctx._source.array_1.add(params.data)&quot;,
        &quot;lang&quot;: &quot;painless&quot;,
        &quot;params&quot;: {
            &quot;data&quot;: {
                &quot;field1&quot;: &quot;abc&quot;,
                &quot;field2&quot;: 3
            }
        }
    }
}&#39;

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 -  &lt;doc_id&gt; RequestError(400, &#39;illegal_argument_exception&#39;, &#39;failed to execute script&#39;)
Traceback (most recent call last):
  File &quot;/&lt;file_path&gt;&quot;, line 137, in index_doc
    client.update(
  File &quot;/Library/Python/3.9/site-packages/elasticsearch/client/utils.py&quot;, line 347, in _wrapped
    return func(*args, params=params, headers=headers, **kwargs)
  File &quot;/Library/Python/3.9/site-packages/elasticsearch/client/__init__.py&quot;, line 2092, in update
    return self.transport.perform_request(
  File &quot;/Library/Python/3.9/site-packages/elasticsearch/transport.py&quot;, line 466, in perform_request
    raise e
  File &quot;/Library/Python/3.9/site-packages/elasticsearch/transport.py&quot;, line 427, in perform_request
    status, headers_response, data = connection.perform_request(
  File &quot;/Library/Python/3.9/site-packages/elasticsearch/connection/http_urllib3.py&quot;, line 291, in perform_request
    self._raise_error(response.status, raw_data)
  File &quot;/Library/Python/3.9/site-packages/elasticsearch/connection/base.py&quot;, line 328, in _raise_error
    raise HTTP_EXCEPTIONS.get(status_code, TransportError)(
elasticsearch.exceptions.RequestError: RequestError(400, &#39;illegal_argument_exception&#39;, &#39;failed to execute script&#39;)

答案1

得分: 0

根据官方文档(8.x),您不需要指定body,而是直接使用脚本:

client.update(
    index=index,
    id=doc_id,
    routing=doc_id,
    script=script            &lt;------
)
英文:

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            &lt;------
        )

答案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.

&quot;source&quot; : &quot;if (ctx._source.array_1 == null) { ctx._source.array_1 = [params.data]; } else {ctx._source.array_1.add(params.data)} &quot;

huangapple
  • 本文由 发表于 2023年3月7日 15:13:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/75658939.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定