当前位置: 首页 > 面试题库 >

elasticsearch:使用脚本更新嵌套字段?

庾君博
2023-03-14
问题内容

我想在nested每个更新时间将一个对象添加到字段中。

例如,我有一个文档:

{
    "test":[{"remark":"remark1"}]
}

下次,我想在remark测试字段中添加一个对象并保存旧remark对象。结果是:

{
    "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:\na8220b2cf14b8b7ebeead7f068416882d04fa25d: 1: \nclass 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.\n   CILastCallResultRemark ?: []) += remarkI\n                                 ^\n\n1 error\n"
            }
        }
    }
},
"status": 400
}

编辑

现在,我想添加一个字段以确保更新或插入对象。例如:

{
    "test":[{"remark":"remark1","id":"1"}]
}

当我更新字段时,当id存在时,我将更新对象。相反,我将插入对象。


问题答案:

我建议尝试这样的脚本,该脚本在参数中带有两个参数。它将检查任何嵌套对象是否已经包含给定的id:

  • 如果是,它将更新给定 remark
  • 如果没有,它将在test数组中插入一个新的嵌套对象。

脚本如下所示:

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)
}

内联并使用适当的分号后,脚本如下所示:

{
    "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"
        }
    }
}


 类似资料:
  • 有没有办法在嵌套查询中使用“script_fields”,将字段添加到返回的inner_hits?例: 我执行n个嵌套查询,向每个嵌套查询传递一组特定的参数。这个想法是让源脚本根据提供的参数为每个内部命中的重叠字段分配一个值。 看起来在同一嵌套路径上执行更多的嵌套查询,定义不同的inner_hits使 ES 去除inner_hits匹配项。例: 如果像这样运行更多的嵌套查询,我会得到正确的匹配项,

  • 问题内容: 我正在使用Java API对Elasticsearch进行CRUD操作。 我有一个带有嵌套字段的类型,我想更新此字段。 这是我对类型的映射: 当然,我的最终用户类型将具有其他参数。 现在,我想将此文档添加到我的嵌套字段中: 我在文档中搜索有关如何更新嵌套文档的信息,但找不到任何东西。例如,我在字符串中具有先前的JSON对象(我们将此字符串称为json)。我尝试了以下代码,但似乎无法正常

  • 以下是我的查询的简化版本: 希望有办法解决这个... 提前感谢你的帮助

  • 问题内容: 我正在尝试使用类似于此处概述的技术,通过Java API在Elasticsearch中更新嵌套对象。问题是如何将json传递到脚本中。如果我只是像这里建议的那样盲目地将json连接到脚本字符串,则Groovy无法编译。如果直接将其作为参数传递,则只会将其解析为字符串。如果我尝试使用JsonSlurper,例如: 我收到一个编译异常:无法解析类groovy.json.JsonSlurpe

  • 我想从特定字段中搜索关键字并返回文档。在这些文档之上,我希望遍历每个嵌套对象,并从选定文档的同一特定字段中再次搜索关键字。 如果关键字存在,则检查:如果布尔isCurrent = True,则设置isCurrent=0,并将该值追加到列表中;否则,如果isCurrent = False,则取当前日期时间的差值,结束日期时间,并获得以月为单位的值,并将该值追加到列表中。 最后,从每个文档的列表中获取

  • 问题内容: 这是我的文件 我想在数组字段“ b”中找到元素并更新整个对象。我尝试了此脚本,但它没有更新。有任何想法吗? 问题答案: 使用此代替: