how to get number of documents which is created today with mongoose? I'm using MEAN stack. I read Mongoose Api Docs but doesn't understand anything :/
By default there is no way.
Documents don't have creation date associated with them unless you explicitly store it in MongoDB.
In other words your Mongoose schema should have something like created field:
const blogSchema = new Schema({
created: {type: Date, default: Date.now}
});
Then search for matching docs:
const now = new Date();
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
doc.find({created: {$gte: today}}).exec(callback);
Supposing you have the date field createdAt in your schema and you would like to get the number of users registered today, you should create a two date object instances to use in your date range query, start and end dates.
Your start date object should hold the current date time hours at 00:00:00.000 (milliseconds precision) and set the hours for today's date to 23:59:59.999 to the end date variable:
var start = new Date();
start.setHours(0,0,0,0);
var end = new Date();
end.setHours(23,59,59,999);
Then pass the modified date objects as usual in your MongoDB aggregation pipeline in the $match operator:
var pipeline = [
{
"$match": {
"createdAt": { "$gte": start, "$lt": end }
}
},
{
"$group": {
"_id": null,
"count": { "$sum": 1 }
}
}
];
Model.aggregate(pipeline, function (err, result){
if (err) throw new Error();
console.log(JSON.stringify(result));
});
If you are using the momentjs library, this can be done by using the startOf() and endOf() methods on the moment's current date object, passing the string 'day' as arguments:
var start = moment().startOf('day'); // set to 12:00 am today
var end = moment().endOf('day'); // set to 23:59 pm today
Related
I wanna Request from nodejs Sequelize to mysql to data of a date that comes from query and there may not be any date
Actually I have no idea how to search by date but i thought it can be with params
can any one help me
Here is what I tried:
.findAndCountAll({
where: {
[Op.or]: [
{ createdAt: { [Op.eq]: moment("2023-01-15").toDate() } },
]
})
and when i send date from react as a string and in nodejs i change it to date time it will show the day before date
ex:
console.log(moment(2023-01-15).toDate())
// 2023-01-14T21:00:00.000Z
You can build your filter if date is present and use $between to filter the previous day:
const date = "2023-01-15";// Some date you received from the client or empty
let where = {};
if (date) {
// Filter day before date
const endDate = moment(date).toDate();
const startDate = endDate;
startDate.setDate(startDate.getDate() - 1);
where = {
from: { $between: [startDate, endDate] },
}
}
// Execute the query
.findAndCountAll(where);
In my application i want to fetch the record on the bases of date i am posting the date like this (2019-07-27) and in my mongodb the date stores like ("created_at" : ISODate("2019-07-27T16:01:24.636+05:00")) but i return empty object how can i solve this problems any body help thanks in advance.
this is my mongodb data
http://prntscr.com/opi9lm
this is my post request
{
"income_frequency" : "daily",
"from_date" : "2019-07-27"
}
this is my controller
const transactionsCredit = await driverTransactionModel.find( {
$and: [
{ user_id: req.userData.userId },
{ transaction_type: mainConfig.transactionType.moneyIn },
{ created_at: req.body.from_date }
]
} ).lean().exec();
var from_date = new Date('2019-07-27'.toISOString());
db.collection.findOne('from_date': {
$lte: from_date
}, function(err, doc) {
if (error) {
console.log(error);
} else {
console.log(doc);
}
});
Note: You can convert date to ISODate and then find documents from collection will resolve your issue.
You need to make 2 dates start date and end date and then match also in DB there's "created_at" which is in date format while date you received from the front end is in a string that's why you need to cast it to date first before matching in the query as
let startDate = new Date(req.body.from_date)
// this will give you date with utc time 00:00:00
let endDate = new Date(new Date(req.body.from_date).setUTCHours(23,59,59))
then match with start and end date in the query:
If you only want data of date of req.body.from_date
const transactionsCredit = await driverTransactionModel.find( {
user_id: req.userData.userId,
transaction_type: mainConfig.transactionType.moneyIn,
created_at:{$gte:startDate,$lte:endDate}).lean().exec();
If you want to fetch data greater than date(req.body.from_date)
const transactionsCredit = await driverTransactionModel.find( {
user_id: req.userData.userId,
transaction_type: mainConfig.transactionType.moneyIn,
created_at:{$gte:startDate}).lean().exec();
I have this mongoose method/query which finds all 'incomes' from a certain user but only if the dates of the 'incomes' are within the current month.
Code:
module.exports.getMonthlyIncome = function(userId, callback){
const now = new Date();
const year = now.getFullYear();
const month = now.getMonth();
const date = now.getDate();
const start = new Date(year, month, 1);
const end = new Date(year, month, 30);
Income.find({owner: userId, date: { $gte: start, $lt: end }}, callback);
}
Result:
[
{
"_id": "58cc9ee50fe27e0d2ced5193",
"amount": 600,
"description": "Ripco Salary",
"owner": "58cc9e950fe27e0d2ced5192",
"__v": 0,
"date": "2017-03-17T00:00:00.000Z"
},
{
"_id": "58ccc3cfca6ea10980480d42",
"amount": 450,
"description": "Another Ripped co salary",
"owner": "58cc9e950fe27e0d2ced5192",
"__v": 0,
"date": "2017-03-26T00:00:00.000Z"
}
]
Result is as expected, gives me the 2 income documents belonging to a certain user during the month.
Now, I want to get the total sum of every 'amount' field from these documents.
So in this case, the sum would be 1050.
How would I achieve this in Mongoose?
Any help is greatly appreciated, cheers.
You can use mongoose Aggregation pipeline to calculate the sum of amount across multiple document.
you need to use $match, to match the query condition, $group to calculate sum across multiple documents.
Income.aggregate([{
$match : { $and : [ {owner: userId}, {date: { $gte: start, $lt: end } }] },
},{
$group : {
_id : null,
total : {
$sum : "$amount"
}
}
}],callback);
Hope this helps!
There are two ways you can do this.
1. Using aggregation queries:
Looks like you are new to mongodb. So, I would not suggest this approach for you. This approach is correctly covered in another answer and that should work totally fine. Do check it out!
2. Using underscore-node:
Rewriting your code:
module.exports.getMonthlyIncome = function(userId, callback){
const now = new Date();
const year = now.getFullYear();
const month = now.getMonth();
const date = now.getDate();
const start = new Date(year, month, 1);
const end = new Date(year, month, 30);
// Including underscore-node
const _ = require('underscore-node');
Income.find({owner: userId, date: { $gte: start, $lt: end }}, function(err, results){
if (err) {
//handle error
}
let sum = _.reduce(results, function(memo, reading){ return memo + reading.amount; }, 0);
// Explaination:
// reduce() accepts an array and a callback function.
// So, we are passing the array in "results"
// In the callback function, do not touch "memo" variable
// Every single object in "results" array will be passed
// to callback function in the "reading" variable
});
Hope this code helps you!
I am unable to think of logic for the following Issue.
Consider I want to Store Data in mongoose in collection called packet where I can store data of different users. I want to purge the data once a certain threshold has been reached (Say for example 10 days). We know that the Mongoose by default gives us CreatedAt and UpdatedAt fields.
Suppose my data is created at 22nd February 2015 and Current Date is 24th February 2015.I will have a PurgeData number(column used for purging of data) as 2 (difference between the two dates). Every day I want to change the value of the PurgeData number by comparing the difference between the current date and the CreatedAt date. I want to schedule this operation every day and delete the data that has reached the threshold so I save memory space. Can Somebody help me with the logic for it and scheduling of the event?
Thanks in Advance
Haven't actually tried this but I would suggest some logic like schedule a job using the mongo-scheduler package where you first do an update and then remove the documents that breach the PurgeData condition. Something like this (untested):
/*
Scheduler Arguments
connection - mongodb connections string (i.e.: "mongodb://localhost:27017/scheduler-db") or a mongoose connection object
options - Options object
*/
var mongoose = require('mongoose');
var Scheduler = require('mongo-scheduer');
var scheduler = new Scheduler(connection, options);
var packet = new mongoose.Schema({
CreatedAt : {type : Date, default: Date.now},
PurgeData : {type : Number, index : true}
});
var Packet = mongoose.model('Packet', packet);
var moment = require('moment');
//Schedule the event.
var event = {
name: 'purge',
collection: 'packet',
after: new Date(),
cron: "0 15 10 * * ?" //cron string representing a frequency - fire at 10:15am every day
};
scheduler.schedule(event)
scheduler.on('purge', function(packet, event) {
console.log(packet.PurgeData)
Packet.find({"PurgeData": {"$lt": 10} }, function (err, packets) {
packets.forEach(function (p){
var days_diff = moment().diff(moment(p.CreatedAt), 'days') // using momentjs library
Packet.update(
{
"_id": p._id
},
{
"$set": {
PurgeData: days_diff
}
}, function (err, doc){
console.log(doc);
});
});
});
Packet.find({"PurgeData": {"$gte": 10} }, function (err, packets) {
packets.forEach(function (p){
Packet.remove({ "_id": p._id }, function (err){
handleErr(err);
});
});
});
})
I am trying to get results from mongodb using nodejs/mongoose.
var dateStr = new Date(year,month,day,0,0,0);
var nextDate = new Date(year,month,day,23,59,59);
GPSData.find({"createdAt" : { $gte : new ISODate(dateStr), $lte: new ISODate(nextDate) }}, function(err, data) {
if(err)
console.log(err);
});
Error: ISODate is not defined
Note that ISODate is a part of MongoDB and is not available in your case. You should be using Date instead and the MongoDB drivers(e.g. the Mongoose ORM that you are currently using) will take care of the type conversion between Date and ISODate behind the scene.
In my case, I was converting a query with ISODates
let dateString = "2014-01-22T14:56:59.301Z";
$gte : ISODate( dateString )
in node.js is
$gte : new Date( dateString )
Convert date to MongoDB ISODate format in JavaScript using Moment JS
MongoDB uses ISODate as their primary date type. If you want to insert a date object into a MongoDB collection, you can use the Date() shell method.
You can specify a particular date by passing an ISO-8601 date string with a year within the inclusive range 0 through 9999 to the new Date() constructor or the ISODate() function. These functions accept the following formats:
new Date("<YYYY-mm-dd>") returns the ISODate with the specified date.
new Date("<YYYY-mm-ddTHH:MM:ss>") specifies the datetime in the client’s local timezone and returns the ISODate with the specified datetime in UTC.
new Date("<YYYY-mm-ddTHH:MM:ssZ>") specifies the datetime in UTC and returns the ISODate with the specified datetime in UTC.
new Date() specifies the datetime as milliseconds since the Unix epoch (Jan 1, 1970), and returns the resulting ISODate instance.
If you are writing code in JavaScript and if you want to pass a JavaScript date object and use it with MongoDB client, the first thing you do is convert JavaScript date to MongoDB date format (ISODate). Here’s how you do it.
var today = moment(new Date()).format('YYYY-MM-DD[T00:00:00.000Z]');
console.log("Next day -- " + (reqDate.getDate() + 1))
var d = new Date();
d.setDate(reqDate.getDate() + 1);
var tomorrow = moment(d).format('YYYY-MM-DD[T00:00:00.000Z]');
You can pass today and tomorrow object to MongoDB queries with new Date() shell method.
MongoClient.connect(con, function (err, db) {
if (err) throw err
db.collection('orders').find({ "order_id": store_id, "orderDate": {
"$gte": new Date(today), "$lt": new Date(tomorrow)}
}).toArray(function (err, result) {
console.log(result);
if (err) throw err
res.send(result);
})
})
Instead of ISO use "new Date" node js will take care of ISO itself, no need to write ISO just simply use "new Date"
You can simply use as follow to convert dates in ISO string :
GPSData.find({"createdAt" : { $gte : new Date(year,month,day,0,0,0).toISOString(), $lte: new Date(year,month,day,23,59,59).toISOString() }}, function(err, data) {
if(err)
console.log(err);
});
if (req.params.sDate && req.params.eDate) {
query["createdAt"] = {
$gte: new Date("2020-01-25").toISOString(),
$lte: new Date("2020-09-25").toISOString()
};
}
console.log("query", query, req.params.limit, req.params.skip);
domain.Payment.find(query)
.limit(req.params.limit)
.skip(req.params.skip)
.sort({ createdAt: -1 })
.exec((err, list) => {
console.log("err", err);
if (err || !list) {
callback(err, null);
} else {