2014-10-18 39 views
1

我有以下下面的“模式”在MongoDB的“操场”托收:如何在MondoDB中多次更新嵌套数组?

{ 
    "_id": ObjectId("54423b40c92f9fffb486a6d4"), 

    "ProjectFileId": 1, 
    "SourceLanguageId": 2, 

    "TargetSegments": [ 
    { 
     "LanguageId": 1, 
     "Segment": "Something", 
     "Colors": [ 
     1, 
     2, 
     3 
     ], 
     "Heights": [ 
     1, 
     2, 
     3 
     ], 
     "Widths": [ 
     1, 
     2, 
     3 
     ] 
    }, 
    { 
     "LanguageId": 1, 
     "Segment": "Something", 
     "Colors": [ 
     1, 
     2, 
     3 
     ], 
     "Heights": [ 
     1, 
     2, 
     3 
     ], 
     "Widths": [ 
     1, 
     2, 
     3 
     ] 
    } 
    ] 
} 

而下面的更新查询:

db.playground.update({ 
    $and: [ 
    { 
     "TargetSegments.Colors": { 
     $exists: true 
     } 
    }, 
    { 
     "ProjectFileId": 1 
    }, 
    { 
     "SourceLanguageId": 2 
    }, 
    { 
     "TargetSegments": { 
     $elemMatch: { 
      "LanguageId": 1 
     } 
     } 
    } 
    ] 
}, 
{ 
    $set: { 
    "TargetSegments.$.Segment": null, 
    "TargetSegments.$.Colors": [], 
    "TargetSegments.$.Widths": [], 
    "TargetSegments.$.Heights": [] 
    } 
}, 
false, true) 

查询执行后的结果是:

{ 
    "_id": ObjectId("54423b40c92f9fffb486a6d4"), 

    "ProjectFileId": 1, 
    "SourceLanguageId": 2, 

    "TargetSegments": [ 
    { 
     "LanguageId": 1, 
     "Segment": null, 
     "Colors": [], 
     "Heights": [], 
     "Widths": [] 
    }, 
    { 
     "LanguageId": 1, 
     "Segment": "Something", 
     "Colors": [ 
     1, 
     2, 
     3 
     ], 
     "Heights": [ 
     1, 
     2, 
     3 
     ], 
     "Widths": [ 
     1, 
     2, 
     3 
     ] 
    } 
    ] 
} 

如您所见,只更新“TargetSegments”数组的第一个元素。

如何在一个更新查询中更新TargetSegments数组的所有元素?

回答

1

因为您使用的是$操作符:位置$操作符标识要更新的数组中的元素(不是多个)要更新而不显式指定数组中元素的位置。要从读取操作中投影或返回数组元素,请参阅$ projection操作符。

您可以使用下面的代码来做到这一点:

db.playground.find({ 
    $and: [ 
    { 
     "TargetSegments.Colors": { 
     $exists: true 
     } 
    }, 
    { 
     "ProjectFileId": 1 
    }, 
    { 
     "SourceLanguageId": 2 
    }, 
    { 
     "TargetSegments": { 
     $elemMatch: { 
      "LanguageId": 1 
     } 
     } 
    } 
    ] 
}).forEach(function(item) 
{ 
    var targets = item.TargetSegments; 

    for(var index = 0; index < targets.length; index++) 
    { 
     var target = targets[index]; 
     target.Segment = null, 
     target.Colors= [], 
     target.Widths= [], 
     target.Heights= [] 
    } 

    db.playground.save(item); 
}); 
+1

我明白了。但这不是一次更新。有什么办法在单个更新操作中做到这一点? – 2014-10-18 19:12:04

+0

MongoDB设计时没有多文档事务,这意味着当您在3个文档上使用** db.coll.update(...)**时,可能会有0到3次失败的更新。在我的解决方案中,有一个mongo使用single-document-transaction =执行save()方法的save()方法,您可能有0到3次失败的更新,与** mongo更新方法相同** – Disposer 2014-10-18 20:10:20

+1

http:// stackoverflow.com/questions/4669178/how-to-update-multiple-array-elements-in-mongodb – Disposer 2014-10-18 20:42:25