如何使用脚本更新Elasticsearch中的JSON对象数组

0 投票
1 回答
1668 浏览
提问于 2025-04-17 21:21

我想在我的ES文档中有一个对象数组。文档的部分映射是

mapping_data = {
        "mappings": {
            config.ES_PAIRS: {
                "properties": {
                    "id": {"type": "string"},
                    "decisions": {
                        "properties": {
                            "user": {"type": "string"},
                            "decision": {"type": "string"}
                        }
                    }
                }
            }
    }

这个决策对象应该是一个数组,用来存储不同的决策,每个决策包括决策内容和做出这个决策的用户。我希望能通过脚本来更新这个文档。

body = {
        "script": "ctx._source.decisions.user += user; ctx._source.decisions.decision += decision",
        "params": {
            "decision": user,
            "user": user
        }
    }
    es.update(index=INDEX_NAME, doc_type=DOC_TYPE, id=ID, body=body)

我正在使用Python客户端。然后我遇到了一个“执行脚本失败”的错误。请帮帮我。

File "/Users/..ve/lib/python2.7/site-packages/elasticsearch/connection/base.py", line 83, in _raise_error
    raise HTTP_EXCEPTIONS.get(status_code, TransportError)(status_code, error_message, additional_info)
elasticsearch.exceptions.RequestError: TransportError(400, u'RemoteTransportException[[Hannibal King][inet[/10.7.103.39:9300]][update]]; nested: ElasticSearchIllegalArgumentException[failed to execute script]; nested: PropertyAccessException[[Error: could not access: user; in class: java.util.ArrayList]\n[Near : {... ctx._source.decisions.user+use ....}]\n             ^\n[Line: 1, Column: 1]]; ')

1 个回答

0

添加一个检查,看看用户和决策对象是否存在,如果存在的话就进行更新。

body = {
    "script": "if (ctx._source.decisions['user'] != null && ctx._source.decisions['decision'] != null) {ctx._source.decisions.user += user; ctx._source.decisions.decision += decision }",
    "params": {
        "decision": user,
        "user": user
    }
}
es.update(index=INDEX_NAME, doc_type=DOC_TYPE, id=ID, body=body)

撰写回答