Reputation: 235
i have collection of objects inside an invitation, having hard time to filter particular object and trigger it's boolean field.
Document:
"Invitation" : [
{
"__v" : 0,
"userID" : ObjectId("54afaabd88694dc019d3b628"),//ObjectId of personA
"__t" : "USER",
"_id" : ObjectId("54b5022b583973580c706784"),
"Accepted" : false
},
{
"__v" : 0,
"userID" : ObjectId("54af6ce091324fd00f97a15f"),//ObjectId of personB
"__t" : "USER",
"_id" : ObjectId("54bde39cdd55dd9016271f14"),
"Accepted" : false
}
]
here i have only two objects inside Invitation array,it can be more than two. Let's say personA and personB send me Invitation, so two different invitation objects are inserted into database having different fields, with objectId of both persons(userID in above document), now if i accept only invitation of personA, it should trigger accepted field of personA object only, here is what i tried so far, but not working as per expectation.
Controller:
User.find({_id: req.user._id},'Invitation',function(err,docs) {
if (err) {
console.log(err);
}
var results = [];
async.each(docs,function(doc,callback) {
async.each(doc.Invitation,function(invite,callback) {
User.findOneAndUpdate(
{'_id': doc._id, 'Invitation._id': invite._id},
{'$set': {'Invitation.$.Accepted': !invite.Accepted}},
function(err,doc) {
results.push(doc);
callback(err);
}
);
},callback);
},function(err) {
if (err)
console.log(err);
console.log('end'+results);
});
});
finally i am looking for a query which can be used to filter a single element or object, like if i accept invitation of personA then Accepted field of personA object should be set to true. i would be really helpful if some logic is provided. Thank you
Upvotes: 0
Views: 93
Reputation: 151122
Not a very clear question. But it seems all you really need to do here is just match the only sub-document you want to update in the first place:
User.find(
{
"_id": "req.user._id",
"Invitation._id": personA.id
},
{ "Invitation.$": 1 },
function(err,docs) {
// and continue
}
);
This is the form of the positional $
operator in a "projection" context. Where only the "singular" matched element is returned.
Once you have a "singular" result, then all the other code works as designed.
I should know after all because I wrote it for you. Not that you are paying any decent respect to that.
Update on Aggregate in Mongodb
Toggle boolean value of subdocuments
Or personA.userID
or whatever makes it work.
Just use the unique identifier for the "user" where you expect that to match the query conditions.
Upvotes: 1
Reputation: 1498
You can do this:
db.user.update({"invitation.userID": 1}, {"$set" : {"invitation.$.Accepted" : true}});
Replacing the value 1 with the user ID you want to update.
The code is in the syntax of MongoShell, simply convert to driver syntax you are using
The operator used was the $
. According to the documentation: The positional $ operator identifies an element in an array to update without explicitly specifying the position of the element in the array. To project, or return, an array element from a read operation, see the $ projection operator.
For more details see: http://docs.mongodb.org/manual/reference/operator/update/positional/
Upvotes: 1