MongoDB $orderby not working with monk - node.js

After following the documentation to the letter, I can not get $orderby to work in NodeJS.
Here is my route in NodeJS:
// gets all the reviews about an instructor
app.get('/findInstructorReviews/:instructorID', function(req, res) {
var commentCollection = req.db.get('comments');
commentCollection.findOne(
{ _id: ObjectID(req.params.instructorID) },
{
$orderby: { 'comments.startDateTime' : -1 }
},
function(err, instructorReviews){debug(err);
if(err) return res.send({ status: 500, data: 'There was an error retreiving the instructor\'s reviews. Please try again later.' });
if(!instructorReviews) return res.send({ status: 404, data: 'This instructor does not have any review yet.' });
return res.send({ status: 200, data: instructorReviews.comments });
});
});
Here is the comments collection in my DB:
> db.comments.find().pretty()
{
"_id" : ObjectId("58d027f003232ca34e43d734"),
"comments" : [
{
"eventID" : ObjectId("58d2cd4e2f77b34b73dd8a04"),
"eventName" : "Yoga in the Park",
"startDateTime" : ISODate("2017-03-22T19:20:00Z"),
"comments" : [
"I really enjoyed his Yoga class.",
"He really helped me stretch out!",
"He taught me doggy style ;)"
]
},
{
"eventID" : ObjectId("58d2cd752f77b34b73dd8a05"),
"eventName" : "Spanish Lessons",
"startDateTime" : ISODate("2017-03-22T19:20:00Z"),
"comments" : [
"Learned a lot!",
"La biblioteca es manana!"
]
},
{
"eventID" : ObjectId("58d4130d5e18cdc928d0b82a"),
"eventName" : "Basketball Practice",
"startDateTime" : ISODate("2017-03-23T18:30:00Z"),
"comments" : [
"great guy! helped me improve my shooting game!",
"really knowledgeable about basketball!",
"excellent coach"
]
}
]
}
The one document in the comments collection is being returned to NodeJS, but not sorted by startDateTime like I want it to. It is being returned in the order it's already in - which would be Yoga, Spanish, Basketball. I've also tried sorting by 1 instead of -1, but that did not change the results.
Can anyone tell me what I am doing wrong?
Edit: I am using monk v1.0.1

Related

Node Output from mongo db as a list of objects

{
"dependencies" : [
{
"name" : "async",
"version" : "2.6.1"
},
{
"name" : "body-parser#1.18.3",
"version" : "1.18.3"
},
{
"name" : "cookie-parser#~1.4.3",
"version" : "1.4.3"
},
{
"name" : "debug#~2.6.9",
"version" : "2.6.9"
},
{
"name" : "express#~4.16.0",
"version" : "4.16.4"
},
{
"name" : "http-errors#~1.6.2",
"version" : "1.6.3"
},
{
"name" : "mongoose",
"version" : "5.3.13"
},
{
"name" : "morgan#~1.9.0",
"version" : "1.9.1"
},
{
"name" : "pug#2.0.0-beta11",
"version" : "2.0.0-beta11"
}
]
}
MongoDB Connected
[ { dependencies:
[ [Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object],
[Object] ] } ]
exports.repo_search = function(req, res, next) {
Repo.findById(req.params.id).populate('repo').exec(function(err, repo) {
if (err) {
return next(err);
}
if (repo == null) {
// No results.
var err = new Error('Repo copy not found');
err.status = 404;
return next(err);
}
Dependencies.find({ Repo_id: '2' }, { dependencies: 1, _id: 0 }).exec(function(err, list_dependencies) {
if (err) {
return next(err);
}
console.log(list_dependencies);
// Successful, so render.
//res.render('dependencies_list', { title: 'Dependencies List', list_dependencies: list_dependencies });
// Successful, so render.
res.render('repo_info_detail', {
title : 'Repo Detail',
repo : repo,
list_dependencies : list_dependencies
// repo_dependencies: results.repo_search
});
// console.log(Repo._id);
});
});
};
Hi, I am using Node and Mongodb with mongoose. I am trying to output a list of dependencies. When i do a console log i get a dependencies list of objects that are called object. The command i am using outputs on the mongo cmd line but when i try to query it in node , and put a console log in my controller i get this. Anybody Know how to fix it ? Thanks in advance.
that's not contain problems with your code.
Try with
console.log(list_dependencies[0]);
If not work, just change from string to object like this
const result = JSON.parse(list_dependencies);
console.log(result)
MongoDB "find" query returns an array(list) of results.(you see a list of objects)
If you are are expecting only one result better use "findOne" query.

Unable to push an item into a MongoDB array within the document while using Waterline

I'm struggling with an update call that just doesn't seem to work for some reason. For some quick context, we have a Node.js application running on Sails.js with Waterline ORM.
As per my package.json file, here are the versions I am using:
connect-mongo: ^1.3.2
mongodb: ^2.2.29
sails: ~0.12.4
sails-mongo: ^0.12.3
I have a collection called "products" and each product looks like this in the database:
{
"_id" : ObjectId("59d5f12025423dc0261c911d"),
"category" : ObjectId("59a9bcf984d756998eaa22e5"),
"status" : "pendingReview",
"isDeleted" : false,
"events" : [
{
"when" : 1507193120,
"actor" : "56cc0f76e1a25cde0d2c15ab",
"action" : "Submitted product",
"note" : "Jeff added this product. It is awaiting review."
}
],
"productId" : "171005-00000",
"createdAt" : ISODate("2017-10-05T08:45:20.538Z"),
"updatedAt" : ISODate("2017-10-05T08:45:20.538Z")
}
I have a UI where a user can "approve" multiple products before they are displayed to website visitors. To do this, I want to just update multiple records by changing the status key to "approved" and adding an event in the events array of each document. The event must be in position 0 of the array. I am trying to update these records with the following code but it doesn't seem to work:
var moment = require('moment');
Products.native(function(error, collection) {
if (error) {
throw error;
}
collection.update(
{ _id: ['59d5f12025423dc0261c911d'] },
{
$set: {
status: 'approved',
$push: {
events: {
when: moment().unix(),
actor: req.body.userId,
action: 'Approved product',
note: req.body.userName + ' approved this product.'
}
}
}
},
{ multi: true },
function(error, count, status) {
if (error) {
sails.log.error(error);
return res.serverError('Database error. Reference ID: ' + req.referenceId);
}
return res.ok(count);
});
});
When I run this query, I don't get any error and when I check my database, the record has not been updated. I get the following data when I run the query:
{
"ok": 1,
"nModified": 0,
"n": 0
}
What's going on here? Why isn't getting updated? If I understand correctly, the query is able to find the document but it isn't getting updated. Is that correct? If yes, how do I resolve this? Thanks.
$push should be at the same level as $set. They are both operators...
This means you should change like this:
{
$set: {
status: 'approved'
},
$push: {
events: {
when: moment().unix(),
actor: req.body.userId,
action: 'Approved product',
note: req.body.userName + ' approved this product.'
}
}
}

mongodb deep update - mongoose .id() causing performance issue

mongoose level collection schema
{
sublevel: [{
"deeplevel": [{
}],
"deeplevel2": [{
}],
}]
}
//routes.js
dlDoc = { "dl1": "dl1" };
db.levels.update({ _id: ObjectId(levelId), "sublevel._id": ObjectId(sublevelId) }, { $push: { "sublevel.$.deeplevel1": dlDoc } }, function (err, updatedDoc) {
if (updatedDoc) {
res.json({ "status": 1 });
res.end();
//calling external apis to update more
result = externalApiResult();
db.levels.findById(level._id, 'sublevel._id sublevel.deeplevel1', function (err, levelFound) {
levelFound.sublevel.id(sublevelId).deeplevel.id(dlDoc._id)['result'] = result;
levelFound.save(function (err, savedDoc) {
});
})
}
});
I need to create and update the level collection's deeplevel1. in my case, the deeplevel1 will be inserted more than 2000 sub docs per day. when i want to update using mongoose .id(deepLevelId) function it is causing me performance issues in the server. is there any way to find the position of deeplevel document inserted once i update the level collection?. so that i can use the position in the update query. And please tell me a best way to update my deeplevel subdocuments without causing performance issues and works fast. thanks in advance.
db.collection.findOne() will be like this.
{
"_id" : ObjectId("563b35d1f07cc9d80a26436b"),
"name":"name",
sublevel:[{
"_id" : ObjectId("569bede3c717b670097519c7"),
"name" : "name",
"deeplevel2" : [{
"_id" : ObjectId("569c559329cc880c18989349"),
"logTime" : new Date("1/18/2016 03:30:48"),
"areaId" : ObjectId("568a6129de552e7dba98d547"),
}, {
"_id" : ObjectId("569c561929cc880c18989354"),
"logTime" : new Date("1/18/2016 03:30:48"),
"areaId" : ObjectId("568a6129de552e7dba98d547"),
}, {
"_id" : ObjectId("569c5945626ffb680e4512e9"),
"logTime" : new Date("1/18/2016 03:30:48"),
"areaId" : ObjectId("568a6129de552e7dba98d547"),
}, {
"_id" : ObjectId("569c594d626ffb680e4512eb"),
"logTime" : new Date("1/18/2016 03:30:48"),
"areaId" : ObjectId("568a6129de552e7dba98d547"),
}
]
}]
}

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

Querying Embedded Documents with NodeJS and Mongoose

I need to query the following data from mongodb:
Project has many Regions, a Region has many Links
Here's the data:
{ "_id" : ObjectId( "4f26a74f9416090000000003" ),
"description" : "A Test Project",
"regions" : [
{ "title" : "North America",
"_id" : ObjectId( "4f26a74f9416090000000004" ),
"links" : [
{ "title" : "A Really Cool Link" } ] },
{ "description" : "That Asia Place",
"title" : "Asia",
"_id" : ObjectId( "4f26b7283378ab0000000003" ),
"links" : [] },
{ "description" : "That South America Place",
"title" : "South America",
"_id" : ObjectId( "4f26e46b53f2f90000000003" ),
"links" : [] },
{ "description" : "That Australia Place",
"title" : "Australia",
"_id" : ObjectId( "4f26ea504fb2210000000003" ),
"links" : [] } ],
"title" : "Test" }
Here's my model setup:
// mongoose
var Link = new Schema({
title : String
, href : String
, description : String
});
var Region = new Schema({
title : String
, description : String
, links : [Link]
});
var Project = new Schema({
title : String
, description : String
, regions : [Region]
});
mongoose.model('Link', Link);
mongoose.model('Region', Region);
mongoose.model('Project', Project);
var Link = mongoose.model('Link');
var Region = mongoose.model('Region');
var Project = mongoose.model('Project');
The query that I'm struggling with is returning a single region object matched on ID. I'm fine returning all of the regions with all of their respective links, but limiting it to the ID of just one region has been a problem.
Here's my broken route that I'm working with:
app.get('/projects/:id/regions/:region_id', function(req, res){
Project.findById(req.param('id'), function(err, project) {
if (!err) {
project.regions.findById(req.params.region_id, function(err, region) {
if (!err) {
res.render('project_regions', {
locals: {
title: project.title,
project: project
}
});
}
});
} else {
res.redirect('/')
}
});
});
I know the above will not work because the object returned by "findById" does not respond to findByID, but it illustrates what I'm trying to do. I tried doing a custom query, but it always returned the entire document, not the single Region that I wanted.
I also tried querying directly off the Region Schema, but that is not returning any results. I assume to query from a Schema that's a subdocument I would have to contextually provide what the parent document is.
In other words, the following does not return an "region" object with data:
app.get('/projects/:id/regions/:region_id', function(req, res){
Region.findById(req.params.region_id, function(err, region) {
if (!err) {
res.render('project_regions_show', {
locals: {
title: "test",
region: region
}
});
} else {
res.redirect('/')
}
});
});
Appreciate any help.
bstar,
You can prevent sub documents from loading by using the query.select:
ie.
Entity.find({ ... })
.select({childentities: 0}) //excludes childentities
.exec(function(err, entities){
...
res.json({entities: entities});
});
I'd recommend extracting the regions into a separate collection with a "projectId: ObjectId()" field. That may give you the querying flexibility you're looking for.

Resources