Mongoose: How to get latest collection data? [duplicate] - node.js

This question already has answers here:
How to get the latest and oldest record in mongoose.js (or just the timespan between them)
(8 answers)
Closed 5 years ago.
I am trying to get the latest collection record from my MongoDB using mongoose.
My current code goes as follows:
ApiData.findOne(
(err, data) => {
if (err) {
// res.status(200).send(err);
}
if (data) { // Search could come back empty, so we should protect against sending nothing back
// res.status(200).send(data);
console.log(data);
} else { // In case no kitten was found with the given query
// res.status(200).send("No kitten found");
}
}, { sort: { _id: -1 }, limit: 1 });
But this does not work in sorting the latest data, only shows the first record.

To get latest added data :
ApiData.findOne({}).sort({date: -1}).exec(function(err, data) {
if (err) {
// res.status(200).send(err);
}
if (data) { // Search could come back empty, so we should protect against sending nothing back
// res.status(200).send(data);
console.log(data);
} else { // In case no kitten was found with the given query
// res.status(200).send("No kitten found");
}
});
To get all data just replace findone with find

I found out my problem after searching Stackoverflow.
The problem was fixed by removing , { sort: { _id: -1 }, limit: 1 }); and adding .sort.({"_id": -1}) to the end of my closing brackets!
Thanks for trying to answer my problem guys!

Related

mongoose: findOne using mongo _id

I get that this can be a duplicated question. I looked up at least 10 related questions and answers, but I am still not able to find the document.
I am trying to get the document using .findOne(). I have the _id that created by MongoDB. But, I get null for every search I try.
await mongoose.connection.db
.collection('testing')
.findOne({ _id: req.body.test_id }, (err, result) => {
if (err) {
res.status(400);
} else {
console.log(`whaaaaaahsidufh ${result}`);
}
});
I tried _id: mongoose.Type.ObjectId(req.body.test_id) and other possible way to search. How can I retrieve the result by using _id on mongoose?
you can use findById();
try {
const test = await mongoose.connection.db.collection('testing').findById(req.body.test_id);
if (test ) {
console.log(`whaaaaaahsidufh ${test}`);
} else {
console.log(`test not found`);
}
}catch(err){
res.status(400);
}

How can I retrieve documents' properties from a pre hook?

I posted this question yesterday because I didn't know how to solve my problem.
Change variable value in document after some time passes?
I was told I need to use a pre hook. I tried to do it, but "this" would refer to the query, not to the document. So I couldn't retrieve the documents to check if the 4 weeks passed. (check the question, you will get it)
Because I don't know how to make this .pre('find') to use variables from each of my document (so it checks if the 4 weeks passed) I was thinking about looping through all of them and checking if 4 weeks passed.
router.get('/judet/:id([0-9]{2})', middleware.access2, function(req, res)
{
var title = "Dashboard";
Somer.find({}, function(err, someri)
{
if(err)
{
console.log(err);
}
else
{
res.render("dashboard", {title: title, id:req.params.id, someri:someri});
}
});
}); ///get route
var someriSchema = new mongoose.Schema({
nume: {type: String, required: true},
dateOfIntroduction: {type:Date, default: Date.now, get: formatareData},
});
someriSchema.pre('find', function(next) {
console.log(this.dateOfIntroduction); <- this will return undefined, because this refers to the query, actually
next();
});///schema and the pre hook. I thought I could use it like this, and inside the body of the pre hook I can check for the date
Here's what I am talking about:
router.get('/judet/:id([0-9]{2})', middleware.access2, function(req, res)
{
var title = "Dashboard | Best DAVNIC73";
Somer.find({}, function(err, someri)
{
if(err)
{
console.log(err);
}
else
{
someri.forEach(function(somer)
{
///check if 4 weeks passed and then update the deactivate variable
})
res.render("dashboard", {title: title, id:req.params.id, someri:someri});
}
});
});
but I think this will be very bad performance-wise if I will get many entries in my DBs and I don't think this is the best way to do this.
So, if I was told correctly and I should use a pre hook for obtaining what I've said, how can I make it refer to the document?
Ok, I think I understood your requirements. this is what you could do:
/*
this will always set a documents `statusFlag` to false, if the
`dateOfIntroduction` was before Date.now()
*/
const mongoose = require('mongoose')
someriSchema.pre('find', function(next) {
mongoose.models.Somer.update(
{ datofIntroduction: { $lte: new Date() }},
{ statusFlag : false})
.exec()
.then((err, result) => {
// handle err and result
next();
});
});
The only problem I see, is that you are firing this request on every find.
in query middleware, mongoose doesn't necessarily have a reference to
the document being updated, so this refers to the query object rather
than the document being updated.
Taken straight from the documentation of mongoose
I pointed you yesterday to their documentation; but here is a more concrete answer.
someriSchema.post('find', function(res) {
// res will have all documents that were found
if (res.length > 0) {
res.forEach(function(someri){
// Do your logic of checking if 4 weeks have passed then do the following
someri.deactivated = true
someri.save()
})
}
})
What this basically do is for every found schema you would update their properties accordingly, your res can have only 1 object if you only queried 1 object. your second solution would be to do the cron
EDIT: This is what you would do to solve the async issue
const async = require('async')
someriSchema.post('find', function(res) {
async.forEach(res, function(someri, callback) {
// Do your logic of checking if 4 weeks have passed
// then do the following - or even better check if Date.now()
// is equal to expiryDate if created in the model as suggested
// by `BenSow`
// Then ONLY if the expiry is true do the following
someri.deactivated = true
someri.save(function (err) {
err ? callback(err) : callback(null)
})
}, function(err){
err ? console.log(err) : console.log('Loop Completed')
})
})

Mongoose find query passing variables [duplicate]

This question already has answers here:
How to query nested objects?
(3 answers)
Closed 5 years ago.
everyone hoping to all are fine. I'm new to node.js and mongodb and i'm having trouble passing in variables to a mongoose model query.
When I pass two arguments, its result is empty and however the record exists.
Retrieving data from MongoDB Image
Sending Get Request through Postman
GET Route: /data/:vehicle_no/:drive_id
URL: http://localhost/api/data/ZXC-1123/drive_234
Route Code:
var reg_no = req.params.vehicle_no;
drive_id: req.params.drive_id;
vehicle.find({
ID: reg_no,
Trip_Details: {
FileName: drive_id
}
}, function(err, result) {
if(err) {
res.json(err);
} else if(result.length > 0) {
res.json("Drive id Found");
} else {
res.json("Drive id not Found");
}
})
Result: Drive id not found
However Expected Result must be: Drive id found
In the above code: Trip_Details is the objects array having file_name, _id, TripData.
And If I pass only one argument like
vehicle.find({ ID: reg_no }
then result found.
Kindly help,
Thanks in Advance
To query based on two parameters, you can also use $and for better readability.
The place where you went wrong is in writing query, second parameter should be written as :
vehicle.find({
ID: reg_no,
Trip_Details.FileName: drive_id
}
Your implementation using $and will be as follows:-
vehicle.find({
$and: [
{ID: reg_no},
{Trip_Details.FileName: drive_id
}]
}, function(err, result) {
if(err) {
res.json(err);
} else if(result.length > 0) {
res.json("Drive id Found");
} else {
res.json("Drive id not Found");
}
})
For more information refer Mongoose Docs

How to find out if insertion or update occured in mongo [duplicate]

This question already has answers here:
Check if MongoDB upsert did an insert or an update
(5 answers)
Closed 8 years ago.
I have the following code in my node.js application where I either update a field or insert a new entry:
DocPrivilege.update({
_id: {
$in: user.documentsPriv
}
}, {
$set: {
access: parseInt(req.body.access),
documentName: req.body.documentName,
documentId: req.body.documentId
}
}, {
upsert: true
}, function(err, updated) {
if (err || !updated) console.log("User not updated");
else {
console.log("User updated");
}
});
Is there a way how I can differentiate if an update or an insertion occured?
You have to use db.getLastError().
It gives you an object with several properties. The property "n" gives you the number of documents updated.
Here's some documentation about it, and here's an example of getLastError in node.js

Mongoose - Increment with findOne

I'm working on some query with Mongoose where I need to skip and limit subdocuments, but in the same query I want to increment some field in document. Currently is my query built with chaining, because I got a lot of problem when I tried to do it just with options. This is what I have:
Model.findOne({ shorten_id: id }).select('title content comments views').slice('comments', [0, 10]).exec(function(err, db_res) { if (err) { throw err; } else { console.log(db_res); } });
I would like to increment filed 'views' for 1 when calling this query, but as I said, I tried a lot of things and it just didn't work.
You can use findOneAndUpdate to modify a document while also fetching one.
Model.findOneAndUpdate({ shorten_id: id }, { $inc: { fieldToIncrement: 1 })
.select('title content comments views')
.slice('comments', [0, 10])
.exec(function(err, db_res) {
if (err) {
throw err;
}
else {
console.log(db_res);
}
});

Resources