在elasticsearch中更新多级嵌套文档

时间:2017-07-24 14:47:44

标签: elasticsearch

使用Elasticsearch 1.7.1,我有以下文档结构

"_source" : {
"questions" : {
    "defaultQuestion" : {           
        "tag" : 0,
        "gid" : 0,
        "rid" : 0,
        "caption" : "SRID",         
    },
    "tableQuestion" : {
        "rows" : [{
                "ids" : {                       
                    "answerList" : ["3547", "3548"],                        
                    "tag" : "0",
                    "caption" : "Accounts",                     
                },
                "name" : {                      
                    "answerList" : ["Some Name"],                       
                    "tag" : "0",
                    "caption" : "Name",                     
                }
            }
        ],
        "caption" : "BPI 1500541753537",
        "id" : 644251570,
        "tag" : ""
    }
},
"id" : "447722821"  
}

我想在questions.tableQuestion.rows中添加一个新对象。我当前的脚本正在用新的对象替换现有的对象。请建议如何追加它。以下是我的更新脚本。

{ "update": {"_id": "935663867", "_retry_on_conflict" : 3} }
{ "script" : "ctx._source.questions += param1", "params" : {"param1" : {"tableQuestion": {"rows" : [ NEWROWOBJECT ]}  } }}

1 个答案:

答案 0 :(得分:2)

您可以使用下一个嵌套字段构建路径,直接到属性,然后使用 + = 运算符。检查 rows 数组是否为null并在这种情况下初始化它也很好。

使用ES 2.4进行检查,但对于早期版本应该类似:

POST http://127.0.0.1:9200/sample/demo/{document_id}/_update

{ 
    "script": {
        "inline": "if (ctx._source.questions.tableQuestion.rows == null) ctx._source.questions.tableQuestion.rows = new ArrayList(); ctx._source.questions.tableQuestion.rows += param1;",
        "params" : {
            "param1" : {
                            "ids": {
                                "answerList": [
                                    "478",
                                    "255"
                                ],
                                "tag": "2",
                                "caption": "My Test"
                            },
                            "name": {
                                "answerList": [
                                    "My Name"
                                ],
                                "tag": "1",
                                "caption": "My Demo"
                            }
                        }
        }
    }
}

对于ES 5.x和无痛语言,脚本有点不同:

POST http://127.0.0.1:9200/sample/demo/{document_id}/_update

{ 
    "script": {
        "inline": "if (ctx._source.questions.tableQuestion.rows == null) { ctx._source.questions.tableQuestion.rows = new ArrayList();} ctx._source.questions.tableQuestion.rows.add(params.param1);",
        "params" : {
            "param1" : {
                            ...
            }
        }
    }
}

更新其他评论

如果路径的某些部分是动态的,您还可以使用参数来构建路径 - 使用get(param_name)方法 - 尝试使用此语法(为简单起见,我删除了空检查):

{ 
    "script": {
        "inline": "ctx._source.questions.get(param2).rows += param1;",
        "params" : {
            "param2" : "6105243",
            "param1" : {
                            "ids": {
                                "answerList": [
                                    "478",
                                    "255"
                                ],
                                "tag": "2",
                                "caption": "My Test"
                            },
                            "name": {
                                "answerList": [
                                    "My Name"
                                ],
                                "tag": "1",
                                "caption": "My Demo"
                            }
                        }
        }
    }
}