Mongoose only sorting dates by time - javascript

I am running a Node.JS server which uses Mongoose to query a MongoDB table that contains a date field. However, when I sort the results by date, they are actually only sorted by the time, disregarding the actual date. For example when I run the query
Competition.find({})
.sort('date')
.exec()
.then(data => {
res.json(data);
})
.catch(console.log);
It returns:
{"_id":"5c6c99e6e7179a27eb63a9a0","date":"2019-02-24T01:00:00.000Z","game_name":"UFO","status":"WAITING","comp_id":7},
{"_id":"5c6b95c8e7179a27eb62e7cf","date":"2019-02-19T06:41:47.185Z","game_name":"UFO","status":"COMPLETED","comp_id":6},
{"_id":"5c6b95b4e7179a27eb62e7cb","date":"2019-02-19T06:41:57.174Z","game_name":"UFO","status":"COMPLETED","comp_id":5},
{"_id":"5c6b95a4e7179a27eb62e7be","date":"2019-02-19T06:42:02.170Z","game_name":"UFO","status":"COMPLETED","comp_id":4},
{"_id":"5c6b9533e7179a27eb62e7a9","date":"2019-02-19T06:42:07.176Z","game_name":"UFO","status":"COMPLETED","comp_id":1},
{"_id":"5c6b958de7179a27eb62e7b8","date":"2019-02-21T18:48:50.497Z","game_name":"UFO_test","status":"COMPLETED","comp_id":3}
You can see here that the first entry has a date of 02-24 so it should show up last, but since the time is 1:00:00 it shows up before the other entries with the dates 02-19 and 02-21, since their times are later (06:41:47 for example).
The schema for the competition table is as follows:
const schema = new mongoose.Schema({
date: Date,
game_name: String,
status: String,
comp_id: Number,
});
I've tried to execute the date sort in a few different ways that Mongoose supports, but they all return the same results. If anyone could provide a fix or a workaround for this issue it would be greatly appreciated!

I had a similar problem and in my case, the dates were not saved as date in mongo like so:
"createdAt": {
"$date": "2018-04-25T22:48:06.863Z"
}
It could be related to the way you are creating your date object. Are you using moment or new Date() or anything else?

Related

How to convert JavaScript Date into PostgreSQL Time (no timezone)?

I use knex with PosgreSQL. I have a table with a Time column.
After trying to insert data in the table, knex throws an error with the following message:
...invalid input syntax for type time: \"2021-07-21T14:40:00.000+03:00\..."
Code example
await knex('table_name')
.insert({ id: 1, time: new Date() })
What is a correct way to preserve JavaScript Date object as a PosgreSQL Time? Should I use 3rd party libs? Or it can be done using knex only?
I was able to fix this issue by manually converting the JavaScript Date object into one of the supported formats of the PostgreSQL.
The 8.5.1.1. Dates and 8.5.1.2. Times chapters have a full list of supported types.
My solution was to use date-fns/format (e.g. format(new Date(), 'HH:mm') // 14:00)
P.S. I'm not sure if this approach is right but it works.

Problem with MongoDB's aggregate function, getting erromessage not understanding why

For school assignment, I've got to execute several MongoDB queries regarding specific problems related to Sales and their details. I'm now getting a problem I haven't encountered before, and being completly new to Mongo doesn't help.
I've been using Robo 3t to help me in the task, and I haven't been able to get anywhere, having tried multiple solutions. I also can't seem to find the problem online, hence me asking here.
So, the code is as it follows:
db.salesdetails.aggregate(
[
{
$project: {
month: { $month: "$OrderDate" },
year: { $year: "$OrderDate" },
store:{$toInt:"$Store"},
ReceiptID:1,
_id:0
}
},
{
$match: {
month: 05,
year: 2011,
store:1046
}
}
])
The expected output would be the Store(an integer, as noted), the month, year and the ID of the Receipt that fall into the specificed timeframe and store.
However, instead of returning it, I get the following error:
https://i.imgur.com/NIYnelc.png
Once I remove the "store:1046" on the match field, the aggregation is sucessful, and I don't have any idea why it is behaving like this.
Thanks in advance.
The error shows you use MongoDB date operators ($month and $year in this case) on a string type. Do a db.salesdetails.findOne() and post the result. I believe you have a string value in OrderDate field instead of a date (ISODate(...)) I have verified on both Compass and Robo 3T that your aggregate pipeline work if the data type is correct.

How to pass a DateTime from NodeJS Sequelize to MSSQL

I have a NodeJS project, and I am trying to pass an 'UpdateDate' field using Sequelize. I am receiving the error 'Conversion failed when converting date and/or time from character string'. I have tried passing a few different things:
Date.now()
new Date().toISOString()
Neither work. Am I missing something simple? I cannot change the column definition on the table. As far as I know, passing a string such as '2016-05-23 10:39:21.000' to a SQL DateTime field works in SSMS, but it seems to be an issue when using Sequelize and Node.
Thanks
Zach
This is caused by a known issue in Sequelize. The solution is to patch Sequelize's date to string format implementation, like explained here, so that all dates are handled properly. Below is the code that fixes the error.
const Sequelize = require('sequelize');
// Override timezone formatting for MSSQL
Sequelize.DATE.prototype._stringify = function _stringify(date, options) {
return this._applyTimezone(date, options).format('YYYY-MM-DD HH:mm:ss.SSS');
};
I figured this out, without changing the data type in the SQL database.
In my Model, I had my column defined as DataTypes.DATE, which, according to the Sequelize documentation, is the equivalent of a DateTime in SQL. However, this was throwing the error. When I changed the definition to DataTypes.STRING, and then added this:
var normalizedDate = new Date(Date.now()).toISOString();
normalizedDate now passes through to the DateTime column in SQL without a problem. The issue that I can tell, is Sequelize was adding a time zone to the Date before passing it. Such as, a date like:
'2017-11-01 16:00:49.349'
was being passed through as:
'2017-11-01 16:00:49.349 +00:00'
and it looks like SQL server does not like the '+00:00'.
I hope this helps others.
You can use this variable:
const timestamps = new Date() + 3600 * 1000 * 7;
I got the same issue. I was able to solve the issue by changing the model as follows.
ex:
create_at: {
type: 'TIMESTAMP',
defaultValue: new Date().toISOString(),
allowNull: false
},
update_at: {
type: 'TIMESTAMP',
defaultValue:new Date().toISOString(),
allowNull: false
}

Trying to sort a find using MongoDB with Meteor [duplicate]

I am working on my first project using Meteor, and am having some difficulty with sorting.
I have a form where users enter aphorisms that are then displayed in a list. Currently the most recent aphorisms automatically display at the bottom of the list. Is there an easy way to have the most recent appear at the top of the list instead?
I tried:
Template.list.aphorisms = function () {
return Aphorisms.find({}, {sort: {$natural:1}});
};
And am stumped because the Meteor docs don't have many examples.
Assuming that the date_created is in a valid date format along with the timestamp, You should insert the parsed value of date_created using Date.parse() javascript function, which gives the number of milliseconds between January 1, 1970 and date value contained in date_created.
As a result of that, the most recently added record will contain greater value of date_created than the record inserted before it.
Now when fetching the records, sort the cursor in descending order of the date_created parameter as:
Aphorisms.find({}, {sort: {date_created: -1}});
This will sort records from newer to older.
I've found the following to be a cleaner solution:
Template.list.aphorisms = function () {
return Aphorisms.find().fetch().reverse();
};
Given that entire collection already exists in the reverse order that you would like, you can simply create an array of all the objects and reverse the order.

Time sensitive data in Node.js

I'm building an application in Node.js and MongoDB, and the application has something of time-valid data, meaning if some piece of data was inserted into the database.
I'd like to remove it from the database (via code) after three days (or any amount of days/time spread).
Currently, my solution is to have some sort of member in my Schema that checks when it was actually posted and subsequently removes it when the current time is past 3 days from the insertion, but I'm having trouble in figuring out a good way to write it in code.
Are there any standard ways to accomplish something like this?
There are two basic ways to accomplish this with a TTL index. A TTL index will let you define a special type of index on a BSON Date field that will automatically delete documents based on age. First, you will need to have a BSON Date field in your documents. If you don't have one, this won't work. http://docs.mongodb.org/manual/reference/bson-types/#document-bson-type-date
Then you can either delete all documents after they reach a certain age, or set expiration dates for each document as you insert them.
For the first case, assuming you wanted to delete documents after 1 hour you would create this index:
db.mycollection.ensureIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } )
assuming you had a createdAt field that was a date type. MongoDB will take care of deleting all documents in the collection once they reach 3600 seconds (or 1 hour) old.
For the second case, you will create an index with expireAfterSeconds set to 0 on a different field:
db.mycollection.ensureIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } )
If you then insert a document with an expireAt field set to a date mongoDB will delete that document at that date and time:
db.mycollection.insert( {
"expireAt": new Date('June 6, 2014 13:52:00'),
"mydata": "data"
} )
You can read more detail about how to use TTL indexes here:
http://docs.mongodb.org/manual/tutorial/expire-data/

Categories

Resources