如何在MongoDB文档中根据条件更新数组元素?

11 浏览
0 Comments

如何在MongoDB文档中根据条件更新数组元素?

我有一个包含数组字段的文档,类似于这样:

{ 
  "_id" : "....",
  "Statuses" : [
    { "Type" : 1, "Timestamp" : ISODate(...) },
    { "Type" : 2, "Timestamp" : ISODate(...) },
    //以此类推
  ]
}

我该如何通过指定其Type值,更新特定Status项的Timestamp?

0
0 Comments

问题的出现的原因:用户想要在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

0
0 Comments

从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}] }
);

这样就可以在多个文档中更新匹配条件的数组元素了。

0