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
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);
}
});