Remove an item from an array mongodb equivalent in mongoose - node.js

Doc:
{
"_id" : ObjectId("5399ba7f8035beb2d4717cc0"),
"listName" : "firstList",
"items" : [
{
"pName" : "iPad ",
"pDesc" : "iPad aiiir",
"ownerID" : ObjectId("5399b596c501732dd4d13923"),
"_id" : ObjectId("5399e2cc2d7b0349d89d2b44"),
"dateAdded" : ISODate("2014-06-12T17:26:36.282Z")
},
{
"pName" : "iPhone ",
"pDesc" : "5s",
"ownerID" : ObjectId("5399b596c501732dd4d13923"),
"_id" : ObjectId("5399e2cc2d7b0349d89d2b44"),
"dateAdded" : ISODate("2014-06-12T17:26:36.282Z")
}
]}
I want to remove an item from the "array" items without knowing the _id of the document only the id of the element,
I have this query that finds the element, it works in mongodb shell but doesn't in mongoose,
db.lists.find( {items:
{$elemMatch:{'_id':ObjectId("5399b596c501732dd4d13923")}}} ,
{"items.$":1});
Do you have an idea why ?
Can you please give me the equivalent in mongoose ?
How should I pull the item from the list knowing only its _id ?

This should do the trick:
db.lists.update(
{},
{ $pull: {"items": {"_id" :ObjectId("5399e2cc2d7b0349d89d2b44") }},
{ multi: true }})
For every document in the collection ({} means empty query), it removes every item with the provided _id (in the items array). Without the multi option, only the first document found will be affected

Ok so I found the mongoose solution to my problem thanks to Yves Amsellem.
The mongoose version of his answer is:
Lists.update(
{},
{$pull: {items: {_id: iProductId}}},
{ multi: true },
function(err, data){
console.log(err, data);
}
);

Related

find from last element's(object) field in array of objects in mongoose

How to find data conditionally with mongoose by checking state field last element of history array.
{
"_id" : ObjectId("5ff4360b3a1119002a6b8e04"),
"name" : "sample"
"history" : [
{
"_id" : ObjectId("56b0402a92b2a18116bf51de"),
"state" : "pending"
},
{
"_id" : ObjectId("56b0402a92b2a18116bf51fn"),
"state" : "completed"
}
],
}
I try with following,
collection.find({$expr: {$eq: [{"$arrayElemAt": ["stateHistory", -1]}, "completed"]}})
Is there way to do this using find function without using aggregation?
you can use $where
collection.find({
$where: function(){
return this.history[this.history.length-1].state === "completed"
}
})

MongoDB - Update objects remove item in send array in object (nested updating)

this is my mongodb object
{
"_id" : ObjectId("4faaba123412d654fe83hg876"),
"user_id" : 123456,
"posters" : [ 123456,1111,456789,3333]
}
i want to add an item to posters array , or remove one how could i do it ?
its nested updating.
i saw some question around stackoverflow , but i didnt found any answer how to remove object from the array , lets say 3333 there .
so the result will be :
{
"_id" : ObjectId("4faaba123412d654fe83hg876"),
"user_id" : 123456,
"posters" : [ 123456,1111,456789]
}
Use $pull.
db.collection.update(
{ posters: "3333" },
{ $pull: { posters: "3333" } },
{ multi: true }
)
Use $push to add something into an array :
db.collection.update(
{ $push:
{
"posters" : "0000"
}
}
)
Use $pull to remove something from an array:
db.collection.update(
{ $pull:
{
"posters" : "3333"
}
}, True
)

how to remove nested array value and get all values in a collection in mongoose?

I need to delete a record in a nested array in a collection
mongodb collection is having the following records
{
"_id" : ObjectId("589b043abc2f5a467c13303b"),
"user_id" : ObjectId("5874c174c813822341cb59a7"),
"filename" : [
{
"url" : "images/product_images/file-1486554170465.jpeg",
"_id" : ObjectId("589b043abc2f5a467c13303c")
},
{
"url" : "images/product_images/file-1486554306440.jpeg",
"_id" : ObjectId("589b04c2bc2f5a467c13303f")
}]
}
In that record i need to delete the fist url , which is under in filename array ,then i need the remaining url values , is there any way to implement this , kindly please help me . Thanks ...
You can use the $pull operator. In your case:
Collection
.update({
"_id": ObjectId("589b043abc2f5a467c13303b")
}, {
"$pull": {
"items": {
"_id": ObjectId("589b043abc2f5a467c13303c")
}
}
});

findAndModify usage in node.js/MongoDb

I have a collection which shows a list of users with their favorite movies.
Here is a sample dataset ...
{
"_id" : ObjectId("545c08dcc4d2b8a0243dd4db"),
"mail" : "mickey#mouse.com",
"name" : "Mickey Mouse",
"favorite_movies" : [
{
"name" : "The Green Mile",
"Year" : "1992"
},
{
"name" : "Raging Bull",
"Year" : "1980"
}
],
"watched_movies" : [
{
"name" : "The Green Mile",
"Year" : "1992"
},
{
"name" : "Jaws",
"Year" : "1976"
}
]
}
Now given _id 545c08dcc4d2b8a0243dd4db and a movie
{
"name" : "InterStellar",
"Year" : "2014"
}
and if I need to add this to the watched_movies, in Node.js/MongoDB, I believe the only way is to
Find the document using Find
Do a findAndModify on the found document by appending to the watched_movies array.
Step #2 is based on example here
http://mongodb.github.io/node-mongodb-native/markdown-docs/insert.html
Is there a better way to do this ? Specifically can I avoid the step#1 ?
Here is how I'm doing step#2.
But I'm forced to do step#1 to get the "watched_movies" element and then append the new movie to it to construct the movielist
//try to update
collection.findAndModify(
{'_id':new BSON.ObjectID(id)}, //query
[['_id','asc']], //sort order
{$set: {"watched_movies": movielist}}, //replacement
{new: true}, //options
function(err, newObject){
if(err) {
console.warn(err.message);
} else {
console.log("Updated !! " + JSON.stringify(newObject));
res.send(object);
}
});
I am also open to suggestions on improving this schema design.
You can do this with a single findAnyModify call by using the $push or $addToSet array operator to directly add the new movie to the watched_movies array:
var movie = {
"name" : "InterStellar",
"Year" : "2014"
};
collection.findAndModify(
{'_id':new BSON.ObjectID(id)},
[['_id','asc']],
{$addToSet: {"watched_movies": movie}},
{new: true},
function(err, newObject){
if(err) {
console.warn(err.message);
} else {
console.log("Updated !! " + JSON.stringify(newObject));
res.send(newObject);
}
});

mongoDB - Update query adding an array document to an existing document

The userlist collection contains documents of the following format.
{
"_id" : ObjectId("5381d32ce72cc794166eede2"),
"name" : "Haseeb",
"password" : "dgkhan",
"email" : "hasseeb#yahoo.com",
"address" : "237 D, Faisal Town , Lahore",
"phone" : "5162806"
}
I intend to add another member in the existing document such that the resultant document looks like this.
{
"_id" : ObjectId("5381d32ce72cc794166eede2"),
"name" : "Haseeb",
"password" : "dgkhan",
"email" : "hasseeb#yahoo.com",
"address" : "237 D, Faisal Town , Lahore",
"phone" : "5162806",
"purchases" : [{
"itemID": xyz,
"quantity": 142
},
{
"itemID": kjh,
"quantity": 987
}
}]
}
For this I have written the following mongoskin query, but it is not performing any updates.
db.collection('userlist').update(
{_id:req.session._id},
{
'$push': { purchases: {
itemID: item.ID,
quantity: item.quantity
}
}
}, function(err) {
if (err) throw err;
console.log('Updated!');
});
}
Value of req.session._id = 5381d32ce72cc794166eede2 i.e a valid _id field of a docuemnt in my collection whereas item.ID and item.quantity are also valid strings.
Any help would be really appreciated.
I'm more familiar with Mongoose, but looking at the docs you could probably either use:
collection.updateById(req.session._id, ...)
or
collection.update({_id: toObjectID(req.session_id)}, ...)
I think you should be using $set instead of $push.
A good resource for this specific question is: http://docs.mongodb.org/manual/reference/method/db.collection.update/#db.collection.update
Something like this. You need to include the $each syntax.
db.collection('userlist').update(
{_id:req.session._id},
{
$push { purchases: { $each: {
itemID: item.ID,
quantity: item.quantity
}
}
}
}, function(err) {
if (err) throw err;
console.log('Updated!');
});
}

Resources