I have a mongodb document, for a project
object:
{
members: [
{ _id: ObjectId(1),
active: true },
{ _id: ObjectId(2),
active: false }
]
}
I'd like to change project.members[1].active = true
, while only knowing ObjectId(2)
during the initial query. Is there a way to do this without using findOne
and manually looping over the members array and checking for equivalence of the ObjectId?
Using http://docs.mongodb.org/manual/reference/operator/update/positional/ , I figured it out.
db.collection('projects').findAndModify(
{ // Query
"_id": ObjectId(id),
"members._id": ObjectId(user_id)
},
[[]], // Ordering
{ // Update parameters
$set: { "members.$.active": true }
},
{new: true}, // Options
function(err, project) {
// do stuff
});
Since the $ positional operator selects the first query match, it'll $set
the active property for only that object in the array.
$pull
and $push
cannot be used simultaneously currently, but is under consideration . "err": "Field name duplication not allowed with modifiers"
I think I can use a $pull
and a $push
to achieve what I need.
db.collection('projects').findAndModify(
{ // Query
"_id": ObjectId(id),
"members": { $elemMatch: { _id: ObjectId(user_id) } } },
[[]], // Ordering
{ // Update parameters
$pull: { "members": { $elemMatch: { _id: ObjectId(user_id) } } },
$push: { "members": ObjectId(user_id), active: true }
},
{new: true}, // Options
function(err, project) {
// do stuff
});
The "members" line of the query is optional - adding this line will restrict the update so that only users already in the members
array can get changed. If it is removed, then running this will overwrite or create a new member.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.