Mongodb 多次更新嵌入文档';性质
我有以下收藏:Mongodb 多次更新嵌入文档';性质,mongodb,Mongodb,我有以下收藏: { "Milestones" : [ { "ActualDate" : null, "Index": 0, "Name" : "milestone1", "TargetDate" : ISODate("2011-12-13T22:00:00Z"), "_id" : ObjectId("4ee89ae7e60fc615c42e28d1")}, { "A
{
"Milestones" : [
{ "ActualDate" : null,
"Index": 0,
"Name" : "milestone1",
"TargetDate" : ISODate("2011-12-13T22:00:00Z"),
"_id" : ObjectId("4ee89ae7e60fc615c42e28d1")},
{ "ActualDate" : null,
"Index" : 0,
"Name" : "milestone2",
"TargetDate" : ISODate("2011-12-13T22:00:00Z"),
"_id" : ObjectId("4ee89ae7e60fc615c42e28d2") } ]
,
"Name" : "a", "_id" : ObjectId("4ee89ae7e60fc615c42e28ce")
}
我想更新明确的文档:已指定_id、里程碑列表。_id和ActualDate为空。
我的dotnet代码如下所示:
var query = Query.And(new[] { Query.EQ("_id", ObjectId.Parse(projectId)),
Query.In("Milestones._id", new BsonArray(values.Select(ObjectId.Parse))),
Query.EQ("Milestones.ActualDate", BsonNull.Value) });
var update = Update.Set("Milestones.$.ActualDate", DateTime.Now.Date);
Coll.Update(query, update, UpdateFlags.Multi, SafeMode.True);
或在本机代码中:
db.Projects.update({ "_id" : ObjectId("4ee89ae7e60fc615c42e28ce"), "Milestones._id" : { "$in" : [ObjectId("4ee89ae7e60fc615c42e28d1"), ObjectId("4ee89ae7e60fc615c42e28d2"), ObjectId("4ee8a648e60fc615c41d481e")] }, "Milestones.ActualDate" : null },{ "$set" : { "Milestones.$.ActualDate" : ISODate("2011-12-13T22:00:00Z") } }, false, true)
但只有第一项正在更新。这在当前是不可能的。更新中的标志
multi
表示更新多个根文档。位置运算符只能匹配一个嵌套数组项。在mongodb jira中有这样的情况。你可以投票等待
当前解决方案只能是加载文档、根据需要进行更新并为每个嵌套数组id保存回或多个原子更新
从以下网址获取文件:
当前,$运算符仅适用于
质疑
正如安德鲁·奥西奇(Andrew Orsich)所回答的,这在目前是不可能的,至少不像你希望的那样。但是加载文档、修改数组然后将其保存回将起作用。风险在于其他进程可能会同时修改数组,因此您可能会覆盖其更改。为了避免这种情况,您可以使用乐观锁定,尤其是当数组不是每秒修改一次时
里程碑\u版本
里程碑\u版本
上添加一个查询约束,并将其递增:
db.Projects.findAndModify({
query: {
_id: your_project_id,
milestones_version: expected_milestones_version
},
update: {
$set: {
Milestones: modified_milestones
},
$inc: {
milestones_version: 1
}
},
new: 1
})
里程碑\u版本
),那么这个命令将不执行任何操作,只返回null。我们只需要重新加载文档并重试。如果阵列不是每秒修改一次,那么这种情况将非常罕见,并且不会对性能产生任何影响
此解决方案的主要问题是必须逐个编辑每个项目(no
multi:true
)。您仍然可以编写javascript函数并在服务器上运行。根据他们的JIRA页面,“此新功能从MongoDB 3.5.12开发版本开始提供,并包含在MongoDB 3.6生产版本中”
Thx,安德鲁。我在吉拉对这个问题投了赞成票。我希望他们能实现它。@1gn1ter:这项功能已被批准,但没有计划:(4年后,它是否受支持?@1gn1ter你对此有什么解决方案吗?我正在寻找相同的解决方案