Multiple Queries Express/Mongodb - mongodb

I am using Express/Ejs/Node/Mongodb
I have multiple models Im querying through and three different data sets to do stuff with.
I need to have a function that calculates the average pain level on symptoms & counts the bodyparts most logged.
I don't know how to simplify my route below and attach these functions to them and send them back to the front end to do something with.
Also any good reads on this particular problem.
My route looks like this
app.get('/dashboard', isLoggedIn, (req, res) =>{
let thirtyDays = moment().subtract(30, 'd').format('YYYY-MM-DD')
SymptomModel.find({postedBy : req.user._id, created: {$gte: `${thirtyDays}`} }, function(error, results){
if(error){
console.log('Error: ', error)
} else {
console.log('Found all symptoms from past 30da: ', results)
}
})
TreatmentModel.find({postedBy : req.user._id, created: {$gte: `${thirtyDays}`} }, function(error, results){
if(error){
console.log('Error: ', error)
} else {
console.log('Found all Treatments from past 30da:', results)
}
})
DoctorModel.find({postedBy : req.user._id, created: {$gte: `${thirtyDays}`} }, function(error, results){
if(error){
console.log('Error: ', error)
} else {
console.log('Found all Doctors from past 30da: ', results)
}
})
res.render('dashboard.ejs', {
user: req.user.firstName,
data: `I would be for the last 30 days from ${now}`,
test: "I need this to be the data"
})
});

So I was able to get multiple data sets with the following code after researching and trying more.
I wanted to post this as a response to my question in case anyone else came upon it.
If you have and better suggestions on how to do this I am open to feedback.
app.get('/dashboard', isLoggedIn, async (req, res) =>{
let thirtyDays = moment().subtract(30, 'd').format('YYYY-MM-DD')
const doctorData = await DoctorModel.find({postedBy : req.user._id, created: {$gte: `${thirtyDays}`} })
const treatmentData = await TreatmentModel.find({postedBy : req.user._id, created: {$gte: `${thirtyDays}`} })
//const symptomData = await SymptomModel.find({postedBy : req.user._id, created: {$gte: `${thirtyDays}`} })
SymptomModel.find({postedBy : req.user._id, created: {$gte: `${thirtyDays}`} })
.then(symptomData => {
res.render('dashboard.ejs', {
doctor: doctorData,
symptom: symptomData,
treatment: treatmentData,
user: req.user.firstName
});
})
});//closes route //req res function

Related

Mongoose find between dates, order by ID

So I am trying to find all documents in a database between 'X' and 'X' dates and then order those by userID. This is what I have so far:
await Expense.find(
{'date' :{'$gte': new Date(startDate), '$lte': new Date(endDate)}}),{sort: {_id: 1}}.exec(function(err, data){
if(err){
console.log('Error Fetching Model');
console.log(err);
}
console.log(JSON.stringify(data, null));
expenseArray = data;
console.log(expenseArray);
But it keeps giving me "TypeError: {(intermediate value)}.exec is not a function"
For added clarification I am trying to write this in mongoose:
"SELECT employeeName, SUM(amount)
FROM reimbursements
WHERE d8 BETWEEN '$startDate' AND '$endDate'
GROUP BY employeeName
ORDER BY employeeName;";
What am I doing wrong? Thank you in advance :D
Your query has few syntax issues, Please try this :
Update :
Below old code will work, but it would be better if you try this way :
try {
let data = await Expense.find(
{ 'date': { '$gte': new Date(startDate), '$lte': new Date(endDate) } }).sort({ _id: 1 })
/** .find() will not return null, it will either return [] or [with matched docs] */
if (data.length) { // checks data != []
console.log(data)
} else { // data == []
console.log('Empty - no docs found')
}
} catch (error) {
console.log('Error Fetching Model');
console.log(error);
}
Old :
await Expense.find(
{ 'date': { '$gte': new Date(startDate), '$lte': new Date(endDate) } }).sort({ _id: 1 }).exec(function (err, data) {
/** sort is not an option for .find() not like aggregate, it has to be on cursor which is result of .find() & .exec() should be at end which is either .find() or .sort() */
if (err) {
console.log('Error Fetching Model');
console.log(err);
}
console.log(JSON.stringify(data, null));
expenseArray = data;
console.log(expenseArray)
})
Sample : mongooseModel.find().sort().exec()
Ref : cursor.sort

mongoose findOneAndUpdate query

I am using mongoose for mongodb queries.
My update query returns null.
What am I doing wrong?
The query is as follows:
Model.findOneAndUpdate(criteria, updatedDetails, { 'new': true})
Example -
I have a user profile which I need to update and send the updated profile back to frontend.
User.findOneAndUpdate({mobile: "9999999999999"}, { address: "test address" }, {'new': true} )
But the result comes null instead of the updated profile.
findOneAndUpdate is now desprecated
use update, here is sample code
exports.updateSomething = (req, res) => {
Model.update({
_id: req.params.id
}, {
$set: {
bla: req.body.bla
}
})
.then(data => {
return res.status(200).json({
success: true,
message: 'Updated successfully'
})
})
.catch(err => {
return res.status(200).json({
success: false,
message: err.message
})
})
}

MongoDB query won't return object in my Express API (React)

I have done this so many times before, but I can't seem to find the issue, it's probably something small and stupid. Take a look at the /server.js file here! (Shortened for demonstration purposes)
/* Make Mongoose promise based */
mongoose.Promise = Promise;
mongoose.connect('mongodb://localhost:27017', options);
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error: '));
/* Routes */
app.route('/games')
.post(postGame)
.get(getGames);
app.route('/games/:id')
.get(getGame)
.delete(deleteGame);
app.route("*").get((req, res) => {
res.sendFile('client/dist/index.html', { root: __dirname });
});
const port = 8080;
app.listen(port, () => {
console.log(`Connected! Server listening on port: ${port}`);
});
Then for my Game model, I have that in app/models/game.js.
import mongoose from 'mongoose';
const Schema = mongoose.Schema;
const gameSchema = new Schema(
{
name: {
type: String,
required:true
},
year: {
type: Number,
required:true
},
description: {
type: String,
required:true
},
picture: {
type: String,
required:true
},
postDate : { type: Date, default: Date.now }
}
);
export default mongoose.model('Game', gameSchema);
This is where I believe I am having the issue.
/* Import Game model schema */
import Game from '../models/game';
const getGames = (req, res) => {
Game.find({}, (err, games) => {
console.log(err, games)
if (err) {
res.send(err);
}
res.json(games);
});
}
const getGame = (req, res) => {
const { id } = req.params;
Game.findById(id, (err, game) => {
if (err) {
res.send(err);
}
res.json(game);
});
}
const postGame = (req, res) => {
let game = Object.assign(new Game(), req.body);
game.save(err => {
if (err) {
res.send(err);
}
res.json({ message: 'Game successfully created!' });
});
};
const deleteGame = (req, res) => {
Game.remove(
{ _id: req.params.id },
err => {
if (err) {
res.send(err);
}
res.json({ message: 'Game successfully deleted!' });
}
);
};
export {
getGames,
getGame,
postGame,
deleteGame
};
Just do be clear... I went into the mongo shell.
I did...
connecting to: test
> db.createCollection('Game')
> db.Game.insert({name: "SSB", year: 2001, description: "Fun Game", picture: "http://google.com", postDate: "2017-01-03T08:51:45.888Z"});
And when I type > db.Game.find({}); I am returned with exactly what I have...
{
"_id" : ObjectId("58c2223e32daa04353e35bdc"),
"name" : "SSB",
"year" : 2001,
"description" : "Fun Game",
"picture" : "http://google.com",
"postDate" : "2017-01-03T08:51:45.888Z"
}
You see when I go to http://localhost:8080/games I am returned with an empty JSON and I just wanna know why. I am 70% sure, it is because it isn't connected to the right collection but I don't remember how to test that :(
I wanted to make this a comment but it won't let me because I don't have a 50 reputation, but I believe I found the issue.
const getGame = (req, res) => {
const { id } = req.params;
Game.findById(id, (err, game) => {
if (err) {
res.send(err);
}
res.json(game);
});
}
In this piece of code you are setting the id to req.params, but you need to set it to req.params.id which is what you passed in your route.
Should look like this:
const {id} = req.params.id;
If you logged id, you would probably get an object that says:
{ id: "[whatever_id_you_put_here]" }
however if you log req.params.id you should get the correct id you put in that spot..
The reason you're getting [] is because you're actually connected to the database and you are actually trying to "get" something, but that something doesn't exist so it sends an empty response.
I hope this helps..

Query mongoDB with mongoose model

Im using the find() method to get all data from a mongoDB like this
exports.getPersona = function (req, res){
Persona.find( function(err, persona) {
if (err)
res.send(err)
res.json(persona); // return all personas in json
}
);
}
Im trying to do a query like this:
exports.getPersona = function (req, res){
Persona.find(
{
faceDetection: {
name: "Borja"
}, function(err, persona) {
if (err)
res.send(err)
res.json(persona);
}
);
}
But i dont find nothing. My mongoose model is:
var faceDetectionSchema = mongoose.Schema({
faceDetection: {
name: String,
surname: String,
}
});
What could be the problem? Thanks a lot.
Edit: the document its a JSON like:
{
"faceDetection": {
"name": "Borja",
"surname": "Good"
}
Looks like your parentheses and braces are out of order. Try this below.
exports.getPersona = function(req, res) {
Persona.find({
'faceDetection.name': "Borja"
}, function(err, persona) {
if (err)
res.send(err)
res.json(persona);
})
}

Updated date field is not updated

I have defined this schema
var docSchema = mongoose.Schema({
name:{type:String,required:true},
}, { timestamps: { createdAt: 'createdAt',updatedAt:'updatedAt' }, collection : 'docs', discriminatorKey : '_type' });
I update the documents using this route
router.post('/:id', auth, function(req,res,next) {
var id = req.params.id;
docA.findByIdAndUpdate(id, req.body, {new: true}, function(err, doc) {
if(err)
res.json(err);
else if(doc==null)
res.status(404).send({
message: "Document not found"
});
else
res.json(doc);
});
});
I noticed updatedAt is not updated when I save some edits to the documents.
Besides this problem, thinking about it, it could be helpful to keep this data in form of array of updated date like:
updatedAt : [
"2016-10-25T12:52:44.967Z",
"2016-11-10T12:52:44.967Z",
"2016-12-01T12:52:44.967Z"
]
SOLUTION(?):According to #chridam suggestions, my current workaround to keep an array of update Dates is:
docSchema.pre(`findOneAndUpdate`, function(next) {
if(!this._update.updateHistory) {
console.log("findOneAndUpdate hook: updateHistory not present")
this._update.updateHistory=[];
}
this._update.updateHistory.push(new Date);
return next();
});
docSchema.pre('save', function (next) {
if(!this.updateHistory) {
console.log("Save hook: updateHistory not present")
this.updateHistory=[];
}
this.updateHistory.push(new Date);
next();
});
This is a known issue, please refer to the original thread on the plugin here, where dunnkers commented:
It's actually impossible to hook middleware onto update,
findByIdAndUpdate, findOneAndUpdate, findOneAndRemove and
findByIdAndRemove in Mongoose at the moment.
This means that no plugin is actually run when using any of these
functions.
Check out the notes section in the Mongoose documentation for
middleware. Issue Automattic/mongoose#964 also describes this.
As a suggested workaround, factoring in your schema changes:
var docSchema = mongoose.Schema({
"name": { "type": String, "required": true },
"updateHistory": [Date]
}, {
"timestamps": {
"createdAt": 'createdAt',
"updatedAt": 'updatedAt'
},
"collection" : 'docs',
"discriminatorKey": '_type'
});
router.post('/:id', auth, function(req,res,next) {
var id = req.params.id;
docA.findByIdAndUpdate(id, req.body, {new: true}, function(err, doc) {
if(err)
res.json(err);
else if(doc==null)
res.status(404).send({
message: "Document not found"
});
else {
doc.updateHistory.push(new Date());
doc.save().then(function(doc){
res.json(doc);
}, function(err) {
// want to handle errors here
})
}
});
});
Another approach would be to attach a hook to the schema:
docSchema.pre("findOneAndUpdate", function() {
this.updatedAt = Date.now();
});