mongodb更新JSON数组

mongodb update on JSON array

本文关键字:数组 JSON 更新 mongodb      更新时间:2023-09-26

我在Mongo:中有这个数据

{'_id':1,
             'name':'Root',
             'taskId':1,
             'parentId':"",
             'path':[1],
             'tasks':[  {"taskId":3,parentId:1,name:'A',type:'task'},
                        {"taskId":4,parentId:1,name:'D',type:'task'},
                        {"taskId":5,parentId:4,name:'B',type:'task'},
                        {'type':'project' , 'proRef':2},
                        {"taskId":6,parentId:3,name:'E',type:'task'},
                        {"taskId":7,parentId:6,name:'C',type:'task'}]
            }

现在我想用新的Json数据更新taskId 6。

var jsonData = {"taskId":6,"name":'Sumeet','newField1':'Val1','newField2':'Val2'}

若字段可用,则查询应更新,否则向现有字段添加新关键字。输出类似

{"taskId":6,parentId:3,name:'Sumeet',type:'task','newField1':'Val1','newField2':'Val2'}]

我尝试了一些查询,但它完全取代了json。

 db.projectPlan.update({_id:1,'tasks.taskId':6},{$set :{'tasks.$':jsonData }});

提前感谢您的帮助!Sumeet

您需要将jsonData变量转换为可以传递给更新的变量。下面是一个示例,它可以完全按照您的示例文档的要求:

var updateData = {};
for (f in jsonData) {
    if (f != "taskId") updateData["tasks.$."+f]=jsonData[f]; 
};
db.projectPlan.update({_id:1, 'tasks.taskId':6}, {$set:updateData})

结果:

{ "_id" : 1, 
  "name" : "Root",
  "taskId" : 1,
  "parentId" : "",
  "path" : [  1 ],
  "tasks" : [
    {   "taskId" : 3,   "parentId" : 1,     "name" : "A",   "type" : "task" },
    {   "taskId" : 4,   "parentId" : 1,     "name" : "D",   "type" : "task" },
    {   "taskId" : 5,   "parentId" : 4,     "name" : "B",   "type" : "task" },
    {   "type" : "project",     "proRef" : 2 },
    {   "taskId" : 6,   "parentId" : 3,     "name" : "Sumeet",  "type" : "task",    "newField1" : "Val1",   "newField2" : "Val2" },
    {   "taskId" : 7,   "parentId" : 6,     "name" : "C",   "type" : "task" } 
] }

您需要手动合并文档:

var jsonData = {"taskId":5,"name":'Sumeet','newField1':'Val1','newField2':'Val2'};
db.projectPlan.find({ _id: 1 }).forEach(
  function(entry) {
    for (var taskKey in entry.tasks) {
      if (entry.tasks[taskKey].taskId === jsonData.taskId) {
        printjson(entry.tasks[taskKey]);
        for (var taskSubKey in jsonData) {
           entry.tasks[taskKey][taskSubKey] = jsonData[taskSubKey];
        }
        printjson(entry.tasks[taskKey]);
      }
    }
    db.projectPlan.save(entry);
  }
);

显然,您可以不使用printjson语句。这只是为了观察原始任务与新任务的合并是否有效。请注意,只要_id字段是唯一的,此查询将只更新单个文档。