假设我有一个这样的文件:
{
"_id" : ObjectId(1234),
"name": "foo",
"bars": [
{ "name": "n1", "myBool": true },
{ "name": "n2", "myBool": false },
{ "name": "n3", "myBool": false }
]
}
我想找到name
(或整个子文档,它并不重要)并将myBool
更改为true
以获取{{1}中的第一个子文档对于原子操作中给定的bars
,当前为false
。例如,根据上述数据,我想在_id
等于{{n2
的文档中返回myBool
并将true
设为n2
_id
1}}。
我怎样才能做到这一点?
答案 0 :(得分:2)
使用参数new set为true运行 findAndModify
命令,从而返回修改后的文档而不是原始文档。
更新应使用$
positional operator标识数组中的元素进行更新,而不显式指定数组中元素的位置。为此,数组字段必须作为查询文档的一部分出现。
输出文档有一个value
字段,其中包含命令的返回文档:
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
}
]
}
答案 1 :(得分:0)
<强>更新强> 可能这是一个解决方案,但满足您的要求,使用以下查询
db.test.findAndModify({
query: { "_id": 123456, "bars.myBool": false},
update: {$set: {"bars.$.myBool": true}},
fields: {
"bars": {$elemMatch: {"myBool" : false }}
}
})
hack是它返回将要修改的原始文档。
返回
{
"_id" : 123456,
"bars" : [
{
"name" : "n2",
"myBool" : false
}
]
}
您可以获取正在更新的文档
所以result
包含带有单个子文档的数组,您可以通过它获取名称。
详细了解findAndModify