Unable to retrieve data after adding fields to find() from mongo - node.js

I have developed a code where I am able to retrieve all videos from filesystem whose file path is stored in mongo database:
app.get("/myvideos", function(request, result){
database.collection("videos").find({}).toArray(function(error, videos){
result.render("myvideos", {
"isLogin": request.session.user_id ? true : false,
"videos": videos
});
});
});
the above code is retreiving the files properly. However I wish to retrieve files of a particular user. My database schema is:
{
"_id" : ObjectId("60914d02185c2a08add68fa2"),
"user" : {
"_id" : ObjectId("60914c73185c2a08add68fa0"),
"name" : "Saumitra Lele",
"image" : "",
"subscribers" : 0
},
"filePath" : "public/videos/1620135170700-bigbuck.mp4",
"thumbnail" : "public/thumbnails/1620135170700-Photo - Saumitra Lele.jpeg",
"title" : "First video uploaded",
"description" : "First video uploaded by Saumitra Lele",
"tags" : "Saumitra Lele video",
"category" : "Technology",
"createdAt" : 1620135170708,
"minutes" : 0,
"seconds" : 32,
"hours" : 0,
"watch" : 1620135170708,
"views" : 0,
"playlist" : "",
"likers" : [ ],
"dislikers" : [ ],
"comments" : [ ]
}
However when I try to retrieve files of a particular user like so it doesn't work:
app.get("/myvideos", function(request, result){
database.collection("videos").find({user:{_id:{$in:[user._id]}).toArray(function(error, videos){
result.render("myvideos", {
"isLogin": request.session.user_id ? true : false,
"videos": videos
});
});
});

I got the solution. This worked:
When user session got logged in, I created a new variable to store user name like so:
request.session.user_name = user.name
Then used the above for comparison as:
app.get("/myvideos", function(request, result){
//var logInId = request.session.user_id;
database.collection("videos").find({"user.name":request.session.user_name}).sort({
"createdAt": -1
}).toArray(function(error, videos){
result.render("myvideos", {
"isLogin": request.session.user_id ? true : false,
"videos": videos
});
});
});
And the above worked properly!

Related

how to find data in array key name nodejs from mongodb

how to find data from mongodb in nodejs i have below query but its return null, i want to find data in child_categories array Key name child_categoryname please help me i am very thanful to you
i am using nodejs i want to find 'truck repair' and in response i want to get child_categoryhrs in response related to truck repair
example = 4
JobCategories.findOne({ child_categories : { child_categoryname : 'truck repair'} })
.exec().then(result => { console.log(result); })
.catch(handleError(res));
//mongodb
{
"_id" : ObjectId("58cea64cfd70bb1aa472ef2c"),
"category_name" : "Repairing",
"date_updated" : ISODate("2017-03-20T12:04:16.323Z"),
"child_categories" : [
{
"child_categoryname" : "truck repair",
"child_categoryhrs" : 4,
"_id" : ObjectId("58cea64cfd70bb1aa472ef2d")
},
{
"child_categoryname" : "car repair",
"child_categoryhrs" : 8,
"_id" : ObjectId("58cfc5405895461b286238fa")
}
],
"__v" : 0
}

Using MongoDB/NodeJS, how can I increment by the number of documents modified in an update query?

I have written an update query in MongoDB/NodeJS that deletes objects from an array of a document, based on the parameters I define. After I pull these objects, I would like to to increment another variable in the document based on how many documents were modified by the update query.
Here is an example of one of my events documents:
{
"_id" : ObjectId("575ed7fca7b89bb4027dded9"),
"dateCreated" : "6/13/2016",
"latitude" : "56.294786195890076",
"longitude" : "-43.59161567687988",
"instructorName" : "Test User",
"instructorEmail" : "test#user.com",
"instructorRating" : 5,
"eventName" : "We gon exercise",
"eventDescription" : "We gon exercise",
"spacesAvailable" : 15,
"streetAddress" : "123 wer",
"city" : "rty",
"state" : "NY",
"zip" : "12332",
"date" : "06/21/2016",
"startTime" : "12:00",
"endTime" : "02:10",
"tags" : [
"Cardio",
"Crossfit"
],
"price" : 5,
"attendies" : [
{
"_id" : ObjectId("5759cfcdb71d80fb2d1203ef"),
"name" : "Buddy Loester",
"email" : "Bud18#gmail.com",
"timeStamp" : 1467048318510,
"payed" : true
},
{
"_id" : ObjectId("574f257b05086e2c7f7940ca"),
"name" : "Trainer Trainer",
"email" : "trainer#user.com",
"timeStamp" : 1467055627894,
"payed" : true
}
],
"unpayed" : 0
}
Here is my code to give a better visualization:
var eventCollection = req.db.get('events');
// get current time since epoch in milliseconds
var milliSinceEpoch = new Date().getTime();
eventCollection.update(
{"attendies.payed" : {$eq : false}},
{
$pull:
{
"attendies" : {"timeStamp": {$lt: milliSinceEpoch /*- 600000*/}}
},
$inc:
{
spacesAvailable: numberAffected
}
},
{
multi: true
}, function(err, numberAffected) {
console.log(numberAffected);
return res.end();
}
);
If I specify 'numberAffected' in the query portion to '1', then it works as expected and increments by 1. However, I would like to increment by the number affected.
I know this code will not work with 'numberAffected' in the query. Using 'numberAffected' in the callback actually does return the number of documents modified by my query.
Does there exist a way in MongoDB to do what I am trying to do?
I have solved my problem by rewriting the query. It is as follows:
var ObjectID = require("mongodb").ObjectID;
var eventCollection = req.db.get('events');
var milliSinceEpoch = new Date().getTime();
// find and return all the documents in the events DB where there is a user who has not payed for an event
// they RSVP'd for
eventCollection.find({"attendies.payed" : {$eq : false}}, function(err, documentsWithUnpayedUsers) {
// if error finding, print it and return
if(err) {
console.log(err);
return res.sendStatus(400, "Error cancelling");
}
// if everyone has payed for all RSVP'd events
if(!documentsWithUnpayedUsers) return res.sendStatus(404, "Everyone has payed!");
// loop through every document which has people who have not yet payed for RSVP'd events
for(var i = 0; i < documentsWithUnpayedUsers.length; i++) {
// for each of these documents:
eventCollection.update(
{_id: ObjectID(documentsWithUnpayedUsers[i]._id)},
{
// remove the user from the attendie list if they have not payed,
// and it has been 10 minutes since they RSVP'd
$pull:
{
"attendies" : {"timeStamp": {$lt: milliSinceEpoch - 600000}, "payed" : {$eq : false}}
},
// then modify the number of spaces available for the event by the number of people who were
// removed from the attendie list
// then modify the amount of people who have not payed for the event yet (will now be 0)
$inc:
{
spacesAvailable: documentsWithUnpayedUsers[i].unpayed,
unpayed: -documentsWithUnpayedUsers[i].unpayed
}
}, function(err) {
// error checking for the update query
if(err){
console.log(err);
return res.sendStatus(400, "There was an error removing an attendie fom the event: "
+ documentsWithUnpayedUsers[i].eventName);
}
}
); // end of update query
} // end of for loop
return res.end();
}
); // end of find()
}); // end of checkPayed

Nodejs Mongoose find query has slow performance

I am having an issue when performing find queries in nodejs with mongoose. While using mongo shell client, for the same query, i get a response in 2-10ms. But when i run that same query with Mongoose i get a response in 400-550ms. I've tried the mongodb driver also, but got same results.
First of all. Laptop specs are as follows: 2 CPU's and 4GB DDR3 RAM. I'm not sure what i am missing here.
mongoose.connect(config.database, function (err) {
if (err) return console.error(err);
console.log('Connected');
var startTime = Date.now();
UserModel.find().lean().exec()
.then(function (docs) {
console.log('Found ' + docs.length + ' documents');
console.log('Finished after ' + (Date.now() - startTime) + 'ms')
mongoose.connection.close();
})
.catch(function (err) {
console.err(err)
});
});
Result:
Connected
Found 2317 documents
Finished after 456ms
Shell:
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 2317,
"executionTimeMillis" : 9,
"totalKeysExamined" : 0,
"totalDocsExamined" : 2317,
"executionStages" : {
"stage" : "COLLSCAN",
"filter" : {
"$and" : [ ]
},
"nReturned" : 2317,
"executionTimeMillisEstimate" : 10,
Update
When limited to 100 on both, i get the following results:
Shell: 0ms
Nodejs: ~70ms
Update
This is an example of the document structure. I have not added it before since it is not complex.
{
"_id" : ObjectId("56e6cfda713e98cc1191cae0"),
"email" : "doppelganger113#gmail.com",
"password" : "$2a$10$egjew7mBQtKMgVbK6uXV5uD1hO8yQZ1tU5nztmVZQ4nfhLovOKN2q",
"firstName" : "Marko",
"lastName" : "Kovacevicc",
"index" : 20100140,
"gender" : "Male",
"role" : "SuperAdmin",
"isActive" : true,
"__v" : 0,
"avatar" : {
"small" : "http://localhost:3000/uploads/avatar/3a8ed7bb-4f60-4f69-b8fc-372d1db9b044.png",
"medium" : "http://localhost:3000/uploads/avatar/246c6067-403d-4e47-9e65-828cfab66d84.png",
"source" : "http://localhost:3000/uploads/avatar/01dbb51c-c957-4f67-ba36-9e8cc227168c.png"
},
"birthDate" : ISODate("1991-11-28T23:00:00Z")
}
Will test this on a server instead locally just to check if it's to the laptop. But still, those searches appear to take a lot of time, which bugs me. I know they are not the same, but i did not expect this much of a difference.Also i accidentally added mongoose debug, it was tested with and without it.
Update
Shell command: db.users.find({}).explain("executionStats")

Fetch sub-document Mongodb only match with criteria

I have data in mongodb like this:
{
"_id" : ObjectId("55a12bf6ea1956ef37fe4247"),
"tempat_lahir" : "Paris",
"tanggal_lahir" : ISODate("1985-07-10T17:00:00.000Z"),
"gender" : true,
"family" : [
{
"nama" : "Robert Deniro",
"tempat_lahir" : "Bandung",
"tanggal_lahir" : ISODate("2015-07-09T17:00:00.000Z"),
"pekerjaan" : "IRT",
"hubungan" : "XXX",
"tanggungan" : false,
"_id" : ObjectId("55a180f398c9925299cb6e90"),
"meta" : {
"created_at" : ISODate("2015-07-11T20:59:25.242Z"),
"created_ip" : "127.0.0.1",
"modified_at" : ISODate("2015-07-12T15:54:39.682Z"),
"modified_ip" : "127.0.0.1"
}
},
{
"nama" : "Josh Groban",
"tempat_lahir" : "Jakarta",
"tanggal_lahir" : ISODate("2015-06-30T17:00:00.000Z"),
"pekerjaan" : "Balita",
"hubungan" : "Lain-Lain",
"tanggungan" : true,
"_id" : ObjectId("55a29293c65b144716ca65b2"),
"meta" : {
"created_at" : ISODate("2015-07-12T16:15:15.675Z"),
"created_ip" : "127.0.0.1"
}
}
]
}
when i try to find data in sub-document, with this code:
person.findOne({ _id: req.params.person, {'family.nama': new RegExp('robert', 'gi') }}, function(err, data){
// render code here
});
It show all data in Family Data,
Can we fetch or display a data only match with criteria/keyword, for example only "Robert Deniro" row
Thank You
In 'regular' MongoDB, you can use the $ operator for that. I'm not sure if it works with Mongoose, but it's worth a try:
person.findOne({
_id : req.params.person,
'family.nama' : new RegExp('robert', 'gi')
}, {
// Only include the subdocument(s) that matched the query.
'family.$' : 1
}, function(err, data){
// render code here
});
If you need any of the properties from the parent document (tempat_lahir, tanggal_lahir or gender; _id will always be included), you need to add them to the projection object explicitly.
One caveat: the $ operator will only return the first matching document from the array. If you need it to return multiple documents, you can't use this method and (AFAIK) have to postprocess the results after they are returned from the database.
It solved with this code:
var options = {
family: {
$elemMatch: { nama: req.query.keyword }
},
};
person.findOne({ _id: req.params.person, 'family.nama': keyword }, options, function(err, data){
//render code here
});
Thanks to #hassansin & #robertklep

mongodb query on nodeJS say cannot read property remove of 'null'

This is my entry in database in mongodb which is of type object in schema
"_id" : ObjectId("5539bed4b417d75d1fee5df7"),
"favMovies" : {
"alternate_ids" : {
"imdb" : "2820852"
},
"studio" : "Universal Pictures",
"abridged_directors" : [
{
"name" : "James Wan"
}
],
"abridged_cast" : [
{
"characters" : [
"Dominic Toretto"
],
"id" : "162652472",
"name" : "Vin Diesel"
},
{
"characters" : [
"Brian O'Conner"
],
"id" : "162654234",
"name" : "Paul Walker"
},
{
"characters" : [
"Louie Tran"
],
"id" : "162684066",
"name" : "Tony Jaa"
},
{
"characters" : [
"Deckard Shaw"
],
"id" : "162653720",
"name" : "Jason Statham"
},
{
"characters" : [
"Luke Hobbs"
],
"id" : "770893686",
"name" : "Dwayne \"The Rock\" Johnson"
}
],
"synopsis" : "Continuing the global exploits in the unstoppable franchise built on speed, Vin Diesel, Paul Walker and Dwayne Johnson lead the returning cast of Fast & Furious 7. James Wan directs this chapter of the hugely successful series that also welcomes back favorites Michelle Rodriguez, Jordana Brewster, Tyrese Gibson, Chris \"Ludacris\" Bridges, Elsa Pataky and Lucas Black. They are joined by international action stars new to the franchise including Jason Statham, Djimon Hounsou, Tony Jaa, Ronda Rousey and Kurt Russell.",
"ratings" : {
"audience_score" : 88,
"audience_rating" : "Upright",
"critics_score" : 82,
"critics_rating" : "Certified Fresh"
},
"release_dates" : {
"theater" : "2015-04-03"
},
"critics_consensus" : "",
"runtime" : 140,
"mpaa_rating" : "PG-13",
"genres" : [
"Mystery & Suspense",
"Action & Adventure"
],
"year" : 2015,
"title" : "Furious 7",
"id" : 771354922
},
"username" : "punk",
"__v" : 0
}
In my Node JS code I use the following query
app.delete('/favMovies/:user/:movid',function(req, res){
var user = req.params.user;
var mid = req.params.movid;
console.log(mid);
console.log(user);
MovModel.find({username:user,'favMovies.id':mid}, function (err, doc) {
doc.remove();
MovModel.find({username: user},function (err, data) {   
res.json(data);
});
});
});
In the above snippet mid is movie id. For the above entry in database mov
"id" : 771354922
and user is username but I am getting following error for my query which is working fine in mongo client.
/Users/pankajtripathi/Documents/ECLIPSE-FILES/MyProject/server.js:132
doc.remove();
^
TypeError: Cannot read property 'remove' of null
at /Users/pankajtripathi/Documents/ECLIPSE-FILES/MyProject/server.js:132:5
at /Users/pankajtripathi/Documents/ECLIPSE-FILES/MyProject/node_modules/mongoose/lib/query.js:1169:16
at /Users/pankajtripathi/Documents/ECLIPSE-FILES/MyProject/node_modules/mongoose/node_modules/kareem/index.js:103:16
at process._tickCallback (node.js:355:11)
You should use findOneAndRemove()
MovModel.findOneAndRemove({username:user,'favMovies.id':mid}, function (err, doc) {
if (err) console.log(err);
res.json(doc);
}
Finds a matching document, removes it, passing the found document (if
any) to the callback. Executes immediately if callback is passed.
I changed the query and its working fine now.
MovModel.findOneAndRemove({username:user,_id:mid}, function (err, doc) {
console.log(doc);
MovModel.find({username: user},function (err, data) {
res.json(data);
});
});

Resources