MongoDB在数组中向上插入子文档并返回更新后的子文档
假设我有这样一个文档:MongoDB在数组中向上插入子文档并返回更新后的子文档,mongodb,Mongodb,假设我有这样一个文档: { "_id" : ObjectId(1234), "name": "foo", "bars": [ { "name": "n1", "myBool": true }, { "name": "n2", "myBool": false }, { "name": "n3", "myBool": false } ] } 我想找到名称(或者整个子文档,其实并不重要),并将栏
{
"_id" : ObjectId(1234),
"name": "foo",
"bars": [
{ "name": "n1", "myBool": true },
{ "name": "n2", "myBool": false },
{ "name": "n3", "myBool": false }
]
}
我想找到名称
(或者整个子文档,其实并不重要),并将栏中第一个子文档的myBool
更改为true
,对于原子操作中给定的\u id
,该子文档当前为false
。例如,对于上面的数据,我想返回n2
并将myBool
设置为true
,用于n2
的文档,该文档的\u id
等于ObjectId(1234)
如何实现这一点?在参数new设置为true的情况下运行命令,从而返回修改过的文档而不是原始文档
更新应该使用,它标识要更新的数组中的元素,而不显式指定元素在数组中的位置。要使其工作,数组字段必须作为查询文档的一部分出现
输出文档有一个值
字段,其中包含命令返回的文档:
var result = db.runCommand({
"findAndModify": "collection",
"query": {
"_id" : 1234,
"bars.myBool": false
},
"update": { "$set": { "bars.$.myBool": true } },
"new": true
});
printjson(result.value);
样本输出
{
"_id" : 1234,
"name" : "foo",
"bars" : [
{
"name" : "n1",
"myBool" : true
},
{
"name" : "n2",
"myBool" : true
},
{
"name" : "n3",
"myBool" : false
}
]
}
更新:
这可能是一个解决方案,但满足您的要求,请使用以下查询
db.test.findAndModify({
query: { "_id": 123456, "bars.myBool": false},
update: {$set: {"bars.$.myBool": true}},
fields: {
"bars": {$elemMatch: {"myBool" : false }}
}
})
黑客是它返回要修改的原始文档
它回来了
{
"_id" : 123456,
"bars" : [
{
"name" : "n2",
"myBool" : false
}
]
}
您可以从中获取正在更新的文档
因此,result
包含带有单个子文档的数组,通过该数组可以获取名称
阅读有关的更多信息是否可以调整为仅返回子文档而不是整个文档?例如,我想知道更改了哪个子文档(名称)。不幸的是,您无法在原子更新中执行此操作。您必须手动筛选数组,即运行两个单独的查询1。查找带有“_id”:1234,“bar.myBool”:false}
的文档,然后运行上面的更新返回修改过的文档。当您获得这两个文档时,您可以在条数组子文档中找到差异。不幸的是,这在高度并发的环境中不起作用,因为两个或多个线程可以同时执行此操作。也就是说,我无法先读取然后比较结果,因为另一个线程可能也更新了“myBool”,然后我不知道更改了哪一个。@Johan-如果您想以原子方式执行此操作,可以使用new:false
,检查文档更新前的情况,以了解会发生什么变化,并推断出新文件。谢谢,但我的问题是我不知道名字。我想在原子操作中获取名称(并更新myBool)。很抱歉,不理解OP,请检查更新的答案。