Reversed result in mongoose - mongodb

I'm trying to get a list of all "Task" documents from my mongoDB in a reverse order, so latest added "Tasks" are first in the list.
Is there a smart way of doing that?
allTasks(){
return Task.find(function (err, allTasks) {
if (err) return console.error(err);
return allTasks;
})
}
UPDATE
Following code solves the problem:
allTasks(){
return Task.find().sort({created_at:-1}).exec(function (err, allTasks) {
if (err) return console.error(err);
con
return allTasks;})
}

Related

Store collection value to variable

I am having issues storing a value in mongodb to a variable to use within my webpage.
When the user fills out a form on my website, I am trying to figure out what the arrivalTrailer was when the user filled out the arrival form.
So far I have
function previousLoad(loadNumber, callback){
CheckCall.find({loadNumber: loadNumber}).sort({date: 'desc'}).limit(1), function(err, arrival){
if (err){
callback(err, null);
}
else {
callback(null, arrival[0]);
}
}};
previousLoad(loadNumber, function(err, arrival){
if (err){
console.log(err);
}
else{
arrivalTrailer = arrival;
console.log(arrival);
}
});
console.log(previousLoad.arrival);
console.log(arrivalTrailer);
Both output as undefined when I try to console.log the variables.
Thank you :D
Try this :
async function previousLoad(loadNumber) {
try {
let resp = await CheckCall.find({ loadNumber: loadNumber }).sort({ date: -1 }).limit(1)
return resp[0]
} catch (error) {
console.log('error ::', error)
throw new Error (error)
}
}
/** You can return response from previousLoad but to test it, Call it from here */
previousLoad(loadNumber).then(resp => { console.log('successfully found ::', resp)}).catch(err => { console.log('Error in DB Op ::', err)});

.find() returning nothing even when data exists

I've a mongo database with 3 collections for 3 different kind of users as User,Partner,Admin. Whenever a new user of any type signup I'm searching all three collections to check if username and email exist already. I'm trying to achieve this by calling a function as:
function checkAttribute(attr,val,callback){
User.find({attr: val},function(err,user){
if(err){
console.log(err);
}else{
if(user.length === 0){
Partner.find({attr: val},function(err,partner){
if(err){
console.log(err);
}else{
if(partner.length === 0){
Admin.find({attr: val},function(err,admin){
if(err){
console.log(err);
}else{
if(admin.length === 0){
return callback(null,true);
}else{
return callback(null,false);
}
}
});
}else{
return callback(null,false);
}
}
});
}else{
return callback(null,false);
}
}
});
};
Calling function line:
checkAttribute("username",newUser.username,function(error,response){
.......
});
But this is not working as it returns true always even when users with passed username/email exists already. I am unable to find the problem. Any one knows why this is happening?
Thanks in advance.
Since you are passing in the attribute as a variable in the function parameters, the query document
{ attr: val } is an object with the key "attr", not the dynamic attribute you pass in.
To fix this, you need to use computed property names in your query object as
{ [attr]: val }
Also, the function can use async/await pattern to be more readable and for the purpose of finding if a document exist findOne does the job so
well as it returns a document if it exists and null otherwise.
So your function can be refactored as
async function checkAttribute(attr, val, callback) {
try {
const query = { [attr]: val }
const user = await User.findOne(query).exec()
const partner = await Partner.findOne(query).exec()
const admin = await Admin.findOne(query).exec()
const found = (user || partner || admin) ? true: false
return callback(null, found)
} catch (err) {
console.error(err)
return callback(err, null)
}
};
attr: in your queries will search for a db field called attr. If you want to use the function parameter attr, use [attr]: as the key.
Example:
attr = 'username'
User.find({ [attr]: val }, function (err, user) {
if (err) {
console.log(err);
}
})
This is a feature available since ES6 so should work fine. See the docs here for more info

Loopback - How to use bulkUpdate method

I'm using Loopback v3 currently and wanted to upsert many records at once in a collection; I found this method bulkUpsert from the documentation (http://apidocs.loopback.io/loopback/#persistedmodel-bulkupdate) but I couldn't figure out how to make it work.
How can I create the updates array from createUpdates() method as mentioned in the documentation? Can anyone help me with a simple example of using this method?
There is an alternative way to do the bulkUpdate method, found in Stackoverflow MongoDB aggregation on Loopback
A mixin can be easily created and reused over the Models. My sample code of bulkUpsert mixin is below:
Model.bulkUpsert = function(body, cb) {
try {
Model.getDataSource().connector.connect(async (err, db) => {
if (err) {
return cb(err);
}
// Define variable to hold the description of the first set of validation errors found
let validationErrors = '';
// Build array of updateOne objects used for MongoDB connector's bulkWrite method
const updateOneArray = [];
// Loop through all body content and stop the loop if a validation error is found
const hasError = body.some(row => {
// Check if it is a valid model instance
const instance = new Model(row);
if (!instance.isValid()) {
// A validation error has been found
validationErrors = JSON.stringify(instance.errors);
// By returning true we stop/break the loop
return true;
}
// Remove ID in the row
const data = JSON.stringify(row);
delete data.id;
// Push into the update array
updateOneArray.push({
updateOne: {
filter: { _id: row.id },
update: { $set: Object.assign({ _id: row.id }, data) },
upsert: true
}
});
// No validation error found
return false;
});
// Check if a validation error was found while looping through the body content
if (hasError) {
return cb(new Error(validationErrors));
}
// No validation data error was found
// Get database collection for model
const collection = db.collection(Model.name);
// Execute Bulk operation
return collection.bulkWrite(updateOneArray, {}, (err, res) => {
// Check if the process failed
if (err) {
console.err('The bulk upsert finished unsuccessfully', err);
return cb(err);
}
// Check if there were errors updating any record
if (res.hasWriteErrors()) {
console.error(`The bulk upsert had ${res.getWriteErrorCount()} errors`, res.getWriteErrors());
}
// Finished successfully, return result
return cb(null, {
received: body.length,
handled: res.upsertedCount + res.insertedCount + res.matchedCount
});
});
});
}
catch (err) {
console.error('A critical error occurred while doing bulk upsert', err);
return cb(err);
}
return null;
};
Ref: Mongodb query documentation

removing multiple document's references using mongoose

I'm currently trying to remove multiple documents references (objectId) when i'm removing those documents.
So this is my code to remove multiple documents and their references:
Comment.find({parentCommentId: req.params.id}).stream()
.on('data', function (comment) {
comment.remove(function (err, result) {
if (err){
console.log(err)
}
console.log(result);
})
})
.on('error', function(err){
// handle error
})
.on('end', function(){
res.status(200).json({
title: 'Comments deleted'
});
});
(this is the middleware i use)
schema.post('remove', function (comment) {
Project.findById(comment.project, function (err, project) {
if(err){
console.log('error : '+ err)
}
project.comments.pull(comment);
project.save();
});
User.findById(comment.user, function (err, user) {
if(err){
console.log('error : '+ err)
}
user.comments.pull(comment);
user.save();
});
});
At the moment i tried multiple things but i kinda got stuck: it removes all the documents i wanted but it always only removes the first document's reference and keeps the other ones.
at this point i don't really understand why.
Have a good day : )

MONGODB mongoose update embedded document in node.js

I have an embedded image document in my main document and I am able to update it as follows. Everytime it updates, it just overrides the existing image and does not add it to the existing images.. I tried by "{images.push: image}", but that does not work. what is the syntax ? I am not sure if i am able to explain the problem. if not, please let me know if i need to add more info here.
var image = {
img : new_file_name,
orig_img_name : files.source.filename,
caption : fields.message,
upload_date : new Date()
};
RentModel.update({'facebook_id':fb_id, 'prop_location.lat':lat, 'prop_location.lng':lng}, {'images':image}, function(err, docs){
if(err) {
console.log("Error during friends update");
throw err;
}
console.log('image updated to database', new_file_name);
});
try to find() the embedded document first and then add the image to the array.
RentModel.find({'facebook_id':fb_id, 'prop_location.lat':lat, 'prop_location.lng':lng}, function (err, item) {
if (err) //throw ...
if (item) {
if (item.images && item.images.length) {
item.images.push(image);
}
else {
item.images = [image];
}
// save changes
item.save(function (err) {
if (!err) {
// done ...
}
});
}
});