如何在MongoDB文档中根据条件更新数组元素?
问题的出现的原因:用户想要在MongoDB文档中更新符合特定条件的数组元素。
解决方法:
从MongoDB shell中可以通过以下方式实现:
db.your_collection.update( { _id: ObjectId("your_objectid"), "Statuses.Type": 1 }, { $set: { "Statuses.$.Timestamp": "new timestamp" } } )
这是C#的等效方法:
var query = Query.And( Query.EQ("_id", "your_doc_id"), Query.EQ("Statuses.Type", 1) ); var result = your_collection.Update( query, Update.Set("Statuses.$.Timestamp", "new timestamp", UpdateFlags.Multi,SafeMode.True) );
这将更新特定的文档,如果想要更新整个集合,可以删除_id过滤器。
值得一提的是,这将仅更新第一个匹配的元素。
还有一个回答解决了可能存在多个匹配的数组元素的情况,链接为:stackoverflow.com/a/68093337/1108305
从MongoDB 3.6版本开始,可以使用$[identifier]定位操作符来更新匹配条件的数组元素。与$定位操作符不同,$[identifier]操作符将更新所有匹配的数组元素。这对于需要更新多个匹配的数组元素的情况非常有用。
在这个例子中,我们想要更新一个指定文档中匹配条件的数组元素的Timestamp字段。我们使用update()方法来实现这个目标。代码如下:
db.yourCollection.update( { _id: "...." }, { $set: {"Statuses.$[element].Timestamp": ISODate("2021-06-23T03:47:18.548Z")} }, { arrayFilters: [{"element.Type": 1}] } );
在这个代码中,arrayFilters选项用于匹配要更新的数组元素,$[element]用于在$set更新操作符中指示只有匹配arrayFilter的数组元素才会被更新。
接下来,问是否可以在updatemany中使用这种方法。答案是肯定的,可以使用这种方法来更新多个文档。具体方法是在updateMany()方法中使用相同的语法和选项。代码示例如下:
db.yourCollection.updateMany( { _id: "...." }, { $set: {"Statuses.$[element].Timestamp": ISODate("2021-06-23T03:47:18.548Z")} }, { arrayFilters: [{"element.Type": 1}] } );
这样就可以在多个文档中更新匹配条件的数组元素了。