Can't find records in Waterline by date/time - node.js

how compare a datetime in sails.js Model? here it is what i did but without luck.
var _date = moment().format('YYYY-MM-DDTHH:mm:ss.SSS') + 'Z';
Game.find({
where:{
active: true,
start: {
'>=' : _date
}
},
limit: 1,
sort: 'start asc'
}, function(err, game) {
console.log('ERROR: ' + err);
console.log('Game OBJ' + game.toString());
});

The datetime type is transformed into an actual Javascript date in Waterline (the Sails ORM). So it needs to be compared against a date object, not a string. You can keep your code exactly as it is, but change the first line to:
var _date = new Date(moment().format('YYYY-MM-DDTHH:mm:ss.SSS') + 'Z');
Then your query should find all Games that start in the future.
Of course since your code is just returning current date, you don't really need moment at all:
var _date = new Date();
will work just as well.

var _date = moment().format('YYYY-MM-DDTHH:mm:ss.SSS') + 'Z';
you need to convert above string variable to date variable using below line
var tempDate = new Date(_date);
Now use $gte instead of '>='
Game.find({
where:{
active: true,
start: {
$gte : tempDate
}
},
limit: 1,
sort: 'start asc'
}, function(err, game) {
console.log('ERROR: ' + err);
console.log('Game OBJ' + game.toString());
});
You can also use $gt, $lt, $lte.

Related

How to save date type dd/mm/yyyy format in mongodb

Tried to save date format like dd/mm/yyyy in mongodb but this is saved like 2020-06-01T18:30:00.000Z.I want to save like 2020-06-01 in mongodb.How to do it?
Here my code:
data.model.js:
const mongoose = require('mongoose');
var userSchemaData = new mongoose.Schema({
p_id: {
type: String
},
product_today: {
type: Date
},
product_afterfive: {
type: Date
}
}, {
versionKey: false,
collection: 'data'
});
module.exports = mongoose.model('Data', userSchemaData);
data.controller.js:
var moment = require('moment');
var todayDate = new Date();
var afterfiveDays = new Date(new Date().getTime() + (5 * 24 * 60 * 60 * 1000));
module.exports.insertData = (req, res, next) => {
let collectionName = req.query.collection;
var Product= mongoose.model(collectionName);
var todayDateFormat = moment(todayDate, 'DD-MM-YYYY').format('MM-DD-YYYY');
var afterfiveDaysFormat = moment(afterfiveDays, 'DD-MM-YYYY').format('MM-DD-YYYY');
var product = new Product({
p_id: "CS1",
product_today:todayDateFormat,
product_afterfive: afterfiveDaysFormat
});
product.save(function(error, document) {
if (error) { console.log(error); } else {
console.log("Successful inserted");
res.json({ success: true, msg: 'User inserted.', cname: collectionName });
}
});
As stated in the documentation, mongoose will create a native Date object from the provided date value (see https://mongoosejs.com/docs/tutorials/dates.html)
The reason for this is probably that MongoDB's underlying type for "date" is
BSON Date is a 64-bit integer that represents the number of
milliseconds since the Unix epoch (Jan 1, 1970). This results in a
representable date range of about 290 million years into the past and
future.
so there's no date-type without the time. You can make sure in your application-code to insert dates with the time set to 00:00:00 or store the the "YYYY-MM-DD"-value as a String instead of a Date.

Sequelize compare with current timestamp

This is my code right now:
const Grace = sequelize.define('grace', {
userId: Sequelize.TEXT,
tribeName: Sequelize.TEXT,
server: Sequelize.TEXT,
hours: Sequelize.INTEGER,
date: Sequelize.DATE,
datef: Sequelize.DATE,
});
As you can see datef is stores as a date. datef is a future date. Example: current time + 36h
else if (command === 'showdb'){
var now = Date.now();
const gracep = await Grace.findAll({
where: {
datef: {
$gt: now,
},
},
});
}
What I want to do is to have it fetch the results in the db, where datef is greather than current timestamp.
The thing is datef is stored as: 2018-06-07 05:11:04.221 +00:00
And the var now is: 1528330290003
So I'm pretty sure that's the reason why it's not working, as it's outputing [], when it shouldn't.
Not sure what to do.
I've used date comparisons in Sequelize for WHERE clause when I want to compare something against the current date.
In my case I converted the current timestamp (from Date.now()) to an ISO string like so:
const now = (new Date()).toISOString();
I didn't have any problems when calling using an [Op.gte] or [Op.lte] operator to compare against the stored dates.
date.now() returns the number of milliseconds since midnight 01 January 1970 UTC. It is the same as new Date().valueOf()
here is what you can do
where : { datef : { [Op.gt]: new Date() } },
Sequelize documentation

Order and limit results in a query with a callback

Using Mongoose, I'd like to make a query with MongoDB and order and limit the results I get. I am doing this with Node.js so I am using callbacks.
So far, I have managed to order my results like this:
myModel.find({ $query: {}, $orderby: { created_at : -1 }}, function (err, items) {
callback( null, items )
});
How can I limit the results I get selecting and index and the number of items I want to get?
Using mongodb native:
http://mongodb.github.io/node-mongodb-native/api-generated/collection.html#find
myModel.find(filter)
.limit(pageSize)
.skip(skip)
.sort(sort)
.toArray(callback);
You can also specify the items in your query:
myModel.find(filter, {sort: {created_at: -1}, limit: 10}, function(err, items){
});
There is no $orderby in node mongodb native, so I'm not sure what library or other tool you're using.
...
Now that you've clarified Mongoose (which in general I recommend against):
myModel.find(filter).limit(10).exec(function(err, items){
//process
});
To sort documents, we can apply sort on a cursor object. To enforce order of sort, instead of passing an object, we need to pass an array to the sort method.
var MongoClient = require('mongodb').MongoClient,
commandLineArgs = require('command-line-args'),
assert = require('assert');
var options = commandLineOptions();
MongoClient.connect('mongodb://localhost:27017/crunchbase', function(err, db) {
assert.equal(err, null);
console.log("Successfully connected to MongoDB.");
var query = queryDocument(options);
var projection = {
"_id": 0,
"name": 1,
"founded_year": 1,
"number_of_employees": 1
};
var cursor = db.collection('companies').find(query);
cursor.project(projection);
cursor.limit(options.limit);
cursor.skip(options.skip);
cursor.sort([
["founded_year", 1],
["number_of_employees", -1]
]);
var numMatches = 0;
cursor.forEach(
function(doc) {
numMatches = numMatches + 1;
console.log(doc.name + "\n\tfounded " + doc.founded_year +
"\n\t" + doc.number_of_employees + " employees");
},
function(err) {
assert.equal(err, null);
console.log("Our query was:" + JSON.stringify(query));
console.log("Documents displayed: " + numMatches);
return db.close();
}
);
});
function queryDocument(options) {
console.log(options);
var query = {
"founded_year": {
"$gte": options.firstYear,
"$lte": options.lastYear
}
};
if ("employees" in options) {
query.number_of_employees = {
"$gte": options.employees
};
}
return query;
}
function commandLineOptions() {
var cli = commandLineArgs([{
name: "firstYear",
alias: "f",
type: Number
}, {
name: "lastYear",
alias: "l",
type: Number
}, {
name: "employees",
alias: "e",
type: Number
}, {
name: "skip",
type: Number,
defaultValue: 0
}, {
name: "limit",
type: Number,
defaultValue: 20000
}]);
var options = cli.parse()
if (!(("firstYear" in options) && ("lastYear" in options))) {
console.log(cli.getUsage({
title: "Usage",
description: "The first two options below are required. The rest are optional."
}));
process.exit();
}
return options;
}
One thing to notice is the order in which MongoDB applies skip, limit and sort
sort
skip
limit
There's also a possibility that we can sort data on the MongoDB side as well, provided that we've setup the indexing.
Notice that MongoDB driver will send a query when we call a cursor method passing a callback function to process query results.

How to populate reference field in virtual method in Mongoose?

I have following schema.
var ItemSchema = new Schema({
name : String
,location: {
address: { type: String, default:''},
geolocation: {longitude: Number, latitude:Number},
place : {type: Schema.Types.ObjectId, ref:'Place'}
},
ranking_in_place : Number })
Place is a reference to Place schema which has name, city, country etc. fields.
I want to create a virtual for ranking_summary:
ItemSchema.virtual('ranking_summary').get(function() {
if(this.ranking_in_place <= 5){
if(this.ranking_in_place == 1){
return "Most popular item" + " in " + this.location.place.name
}
}
})
I cannot get this.location.place.name value because this.location.place is a reference, and not populated. How can I access this value?
Have you made sure to call .populate() on your queries? Otherwise, Mongoose won't know to pull in the reference object. Example:
ItemModel.findOne().populate('place').exec(function (err, item) {
console.log(item.ranking_in_place)
})
Model.find().populate(path, fields, conditions, options);
so for options you could use
{ sort: 'order' } // ascending
{ sort: [['order', 1 ]] } // ascending
{ sort: [['order', 'asc' ]] } // ascending
{ sort: [['order', 'desc' ]] } // ascending
{ sort: [['order', -1 ]] } // descending
{ sort: [['order', 'desc' ]] } // descending
{ sort: [['order', 'descending' ]] } // descending
I think there is no direct method for doing this. One way you can achieve this is by following the hooks. [Read More]
Here is a sample code. I had a need to calculate the totalTime of tutorial which is made up of videos. So, I had to populate videos and then use their duration to calculate totalTime for a tutorial.
tutorialSchema.pre('findOne', function (next) {
this.populate('videos'); // now available as this.ratings in this schema
next();
});
tutorialSchema.virtual('totalTime').get(function () {
let times = [];
times = this.videos.map((v) => {
return v.duration;
});
if(times.length === 0) return 0;
let totalTime = times.reduce((sum, time) => {
return sum + time;
});
return totalTime;
});

ISODate is not defined

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 {

Resources