我正在尝试编写一个脚本,将新用户记录插入ElasticSearch,如果用户已经存在则更新任何信息,并将新的PaymentInfo对象附加到用户的Payments数组(如果更新对象中存在)。这是我到目前为止所使用的简化版本:
curl -XPOST 'http://localhost:9200/usrtest/usr/1/_update' -d '
{
"doc_as_upsert": true,
"doc": {
"customerId": "1",
"firstName": "Mark",
"lastName": "Z",
"emailAddress": "foo.bar@gmail.com",
"paymentInfo": {
"pid": "1",
"amt": "10"
}
}
}'
这几乎可以满足我的需求,因为它可以正确地插入文档,或者如果用户存在具有相同ID的情况下更新文档,但是如果用户已经存在,则缺少将此paymentInfo添加到用户的paymentInfos数组的方面。就像现在一样,它只是覆盖了paymentInfo对象。我已经尝试将此脚本添加到更新JSON:
"script": "if (ctx._source.containsKey(\"paymentInfos\")) {ctx._source.paymentInfos += paymentInfo;} else {ctx._source.paymentInfos = paymentInfo}"
但是弹性搜索会在指定doc
元素时忽略script
个元素。
我觉得我在这里错过了一些愚蠢的东西,但我不确定。这里的任何人都可以帮助我吗?
修改 我也尝试了以下内容:
curl -XPOST 'http://localhost:9200/usrtest/usr/1/_update' -d '
{
"script": "if (ctx._source.containsKey(\"paymentInfos\")) {ctx._source.paymentInfos += paymentInfo;} else {ctx._source.paymentInfos = paymentInfo}",
"upsert": {
"customerId": "1",
"firstName": "Mark",
"lastName": "Z",
"emailAddress": "foo.bar@gmail.com",
"paymentInfo": {
"pid": "1",
"amt": "10"
}
},
"params": {
"paymentInfo": {
"pid": "1",
"amt": "10"
}
}
}'
其中几乎做了我想要的事情,因为它在我多次运行脚本时附加了paymentInfo对象,但是否则它不会更新文档本身(即如果我运行再次编写脚本,将Mark更改为Mindy,它不会更新,因为仅当文档不存在时才使用upsert
元素。
答案 0 :(得分:27)
您需要在脚本的插入部分添加一些数组括号。
"script": "if (ctx._source.containsKey(\"paymentInfos\")) {ctx._source.paymentInfos += paymentInfo;} else {ctx._source.paymentInfos = [paymentInfo]}"
第一部分中的'paymentInfos'属性被定义为一个对象,因此也可能导致您跌倒。