我试图在嵌套数组中找到一条记录,修改它,然后进行投影。
假设我有以下收藏品:
{
"_id" : ObjectId("56558dfc45a06f51decb4ab7"),
"arr" : [
{
"cond" : 1.0000000000000000,
"upd" : 2.0000000000000000
},
{
"cond" : 2.0000000000000000,
"upd" : 3.0000000000000000
},
{
"cond" : 4.0000000000000000,
"upd" : 5.0000000000000000
},
{
"cond" : 6.0000000000000000,
"upd" : 7.0000000000000000
},
{
"cond" : 8.0000000000000000,
"upd" : 9.0000000000000000
}
]
}
我想找到“cond = 4”的记录,将其更新为“upd = 55”并返回记录。
我尝试过以下查询:
db.tests.findAndModify({
query:{
"arr": {"$elemMatch": {"cond":4}}
},
update: {
"$set": {"arr.$": {"cond": 4, "upd": 55, "new": true}}
},
fields: {"arr.$":1}
})
它很好地执行更新,但我收到以下结果:
{
"_id" : ObjectId("56558dfc45a06f51decb4ab7"),
"arr" : [
{},
{},
{},
{},
{}
]
}
*我正在使用MongoDB版本:3.0.7
答案 0 :(得分:2)
您还可以尝试与 positional $
方法一起使用的 findAndModify()
运算符。操作员将识别要更新的数组中的元素,而不显式指定元素在数组中的位置。请注意,数组字段必须作为查询文档的一部分出现,并返回包含对更新所做修改的文档,请使用新选项,因此您的更新将类似于
db.tests.findAndModify({
query: {
"arr.cond": 4
},
update: {
"$set": {"arr.$.upd": 55 }
},
new : true,
fields: { "arr": 1, "_id": 0 }
})
将产生输出:
{
"arr": [
{
"cond" : 1,
"upd" : 2
},
{
"cond" : 2,
"upd" : 3
},
{
"cond" : 4,
"upd" : 55
},
{
"cond" : 6,
"upd" : 7
},
{
"cond" : 8,
"upd" : 9
}
]
}
由于您想要返回更新的文档,通过投影,位置 $ projection
运算符只能用于find()
方法的投影文档或{{1方法所以 findAndModify()
的 findOne()
选项不会使用 $ projection
投影数组的那一部分运营商。
解决方法是在返回的arr字段上使用原生JavaScript filter()
方法
field
这将打印
var result = db.tests.findAndModify({
query: {
"arr.cond": 4
},
update: {
"$set": {"arr.$.upd": 55 }
},
new : true,
fields: { "arr": 1, "_id": 0 }
})
var updated = []
if (result && result.arr) updated = result.arr.filter(function (item) { return item.cond == 4; });
printjson(updated);
- 更新 -
或者您在以下评论中建议的 $elemMatch
投影:
[ { "cond" : 4, "upd" : 55 } ]
<强>输出强>:
var result = db.tests.findAndModify({
query: {
"arr.cond": 4
},
update: {
"$set": {"arr.$.upd": 55 }
},
new : true,
fields: {"arr": {"$elemMatch": { "cond": 4 } }, "_id": 0 }
})
printjson(result);