elasticsearch:使用脚本更新嵌套字段? [英] elasticsearch:use script to update nested field?
问题描述
我想在每次更新时将一个对象添加到 nested
字段中.
I want to add a object into the nested
field every update time.
例如,我有一个文档:
{
"test":[{"remark":"remark1"}]
}
下一次,我想在测试字段中添加一个remark
对象并保存旧的remark
对象.结果是:
Next time,i want to add a remark
object into test field and save the old remark
objects.And the result is :
{
"test":[{"remark":"remark1"},{"remark":"remark2"}]
}
如何实现?
编辑我使用脚本:
{
"script": "ctx._source.test= ((ctx._source.test?: []) += remarkItem)",
"params": {
"remarkItem": {
"remark": "addd"
}
}
}
但是,我得到了例外:
{
"error": {
"root_cause": [
{
"type": "remote_transport_exception",
"reason": "[es77][10.14.84.77:9300][indices:data/write/update[s]]"
}
],
"type": "illegal_argument_exception",
"reason": "failed to execute script",
"caused_by": {
"type": "script_exception",
"reason": "Failed to compile inline script [ctx._source.test= ((ctx._source.test?: []) += remarkItem)] using lang [groovy]",
"caused_by": {
"type": "script_exception",
"reason": "failed to compile groovy script",
"caused_by": {
"type": "multiple_compilation_errors_exception",
"reason": "startup failed:
a8220b2cf14b8b7ebeead7f068416882d04fa25d: 1:
class org.codehaus.groovy.ast.expr.ElvisOperatorExpression, with its value '(ctx._source.test) ? ctx._source.test: []', is a bad expression as the left hand side of an assignment operator at line: 1 column: 82. File: a8220b2cf14b8b7ebeead7f068416882d04fa25d @ line 1, column 82.
CILastCallResultRemark ?: []) += remarkI
^
1 error
"
}
}
}
},
"status": 400
}
编辑
现在,我想添加一个字段以确保更新或插入对象.例如:
Now,i want to add a field to ensure update or insert the object. For example:
{
"test":[{"remark":"remark1","id":"1"}]
}
当我更新字段时,当id存在时,我会更新对象.相反,我会插入对象.
When i update the field,when the id exist,i will update the object.On the contrary,i will insert the object.
推荐答案
我建议尝试这样的脚本,它在参数中使用两个参数.它将检查是否有任何嵌套对象已经包含给定的 id:
I suggest to try a script like this, which takes two parameters in argument. It will check if any of the nested objects already contains the given id:
- 如果是,它将更新给定的
remark
- 如果没有,它会在
test
数组中插入一个新的嵌套对象.
- if yes, it will update the given
remark
- if not, it will insert a new nested object in the
test
array.
脚本是这样的:
def updated = false
ctx._source.test?.each { obj ->
if (obj.id == item.id) {
obj.remark = item.remark
updated = true
}
}
if (!updated) {
ctx._source.test = ((ctx._source.test ?: []) + item)
}
内联并使用适当的分号后,脚本如下所示:
After being inlined and with proper semicolons, the script looks like this:
{
"script": "def updated = false; ctx._source.test?.each { obj -> if (obj.id == item.id) { obj.remark = item.remark; updated = true } }; if (!updated) { ctx._source.test = ((ctx._source.test ?: []) + item)}",
"params": {
"item": {
"remark": "addd",
"id": "1"
}
}
}
这篇关于elasticsearch:使用脚本更新嵌套字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!