Mongo query json object with dates - javascript

I try to dynamically create a mongo query with dates.
This is a part of a JSON query I produced:
{"$or":[{"createdAt":{"$gte":"2017-08-31T22:00:00.000Z"}},{"modifiedAt":{"$gte":"2017-08-31T22:00:00.000Z"}}]}
but it does not work.
This is a part of code which stands behind it:
let result = {$or: [{createdAt: {$lte: new Date(date)}}, {modifiedAt: {$lte: new Date(date)}}]};
Spent 3 hours trying to find a solution. My understanding is that $lte here tries to compare mongo date object with a string describing date in ISO format. And it does not work well.
I do not know how to create a proper JSON object being a mongo query containing dates.
Please help! :-)

If you want to query Mongo with date range, you have to use a standard Date format (ISO-8601). To achieve this, try with moment:
let date ="2019-02-22"; //for example, in my apis, you can set multiple type of date (YYYY-MM-DD, YYYYMMDD, DD-MM-YYYY,..) but date format with / is forbidden.
let query = {$or:[{createdAt: {$lte: moment(date).format()}}, {modifiedAt:{$gte: moment(date).format()}}] //pass parameter to format, in this case it will use the default locale format
Like this you are setting a query. IMO querying on date range with "OR" condition is not useful: usually a date query in is "AND" condition (if you are querying on a single date, your query will be: greater than today or lower than today -> everything)

Related

Mongodb date value to javascript string how to convert?

I logged out the value stored in one of the documents(or notes in my case) in the date key, like this
console.log(notes[0].date)
The output that I got was
and when methods like getDate() or toDateString() didn't work, what should i be doing?
You will need to convert it into a javascript date object using new Date("your mongodb date string");
See: https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Date for more infomation
If your dates are stored using the date data type you should manipulate them as data object in your code.
If your dates are not stored using the date data type you should migrate your data to store the date as date data type rather than string.
You then format the date, using the user’s LOCALE, only when you present it to the user.

Mongoose Query To Get Data For A Particular Date (MongoDB)

I'm having a problem while querying for a particular date in my database
I need to get the data on a particular date
I'm using $gte and $lt mongo functions to conditionally query the date
But I'm not able to get data which corresponds to the date which i need
I'm receiving back all the data from that date till today's date
Because of the $gte(greater than or equal to) function
I'm not able to find a proper solution for this
I tried to look in stackovflw but still couldn't find it
Can someone help me!
This is the query using mongoose I'm trying to get the data only for that particular day
Attendance.find({teacherID:req.body.id,subject:req.body.subject,grade:req.body.grade , section:req.body.section,date:{"$gte": new Date(req.body.date)}}
Maybe you can read the documentation about filter by date at mongoose doc

To clear up some doubts about moment.js

I got stuck in my project, due to some doubts related to moment.js. I'll state some conclusions here I made during writing backend on project, and please can someone correct me if something is wrong?
For example, if I get datetime string from fronted, in format:
"THU 18 MAR 2017 09:20 AM", I should create moment object passing this string to it and corresponding token "ddd DD MMM YYYY HH:mm A" as passed string is not in standard ISO 8601 format.
var datetime = moment(datetimeFromFrontend, "ddd DD MMM YYYY HH:mm A");
Now I have moment object that can be formated in way I want, calling format() function on moment object.
If I want to do some manipulations with datetime generally (for example, compare to today's datetime, or compare only time part), is it mandatory to convert all manipulating datetimes, times or whatever to moment object with same format and using isBefore, isEqual and so on, or can I somehow compare them using >, <, <=, =< ?
If I need to compare (>, < etc) datetime or just time part with value retrieved from SQL database (which is DATETIME or TIME data type), should I pass both comparing values to moment object, convert them in same format and then do manipulations?
And how to save to SQL database column which is DATETIME, or TIME type? Should do some transforms from moment object to string using format()? SQL will automatically convert passing string to corresponding data type?
Example:
var now = moment();
I assume that "now" can't be passed to sql query directly as it is moment object, it should be converted to string (and rely on SQL automatic conversion from string/nvarchar to datetime) or should I save it as moment().toDate() ?
If I need to compare (>, < etc) datetime or just time part with value retrieved from SQL database (which is DATETIME or TIME data type), should I pass both comparing values to moment object, convert them in same format and then do manipulations?
You might want to lookup the docs for that
You have Query functions that can compare moments and even Date objects, for example, this is the entry for the .after function
moment().isAfter(Moment|String|Number|Date|Array);
as you can see, you can pass anything to .isAfter and it will do that job for you
moment().isAfter(new Date(2017, 2, 4))
// true
moment(new Date(2016, 2, 4)).isAfter(new Date(2017, 2, 4))
// false
Of course the easiest way to compare >, < or === is to get the timestamp using Date::getTime, but that's ugly code
And how to save to SQL database column which is DATETIME, or TIME type? Should do some transforms from moment object to string using format()? SQL will automatically convert passing string to corresponding data type?
I think it depends how you SQL works and how your server communicates to it, ORACLE, you should refer to any documentation about storing date objects inside your sql, eventually dates and formats are all about making unix-timestamps human readable/understandable.
I assume that "now" can't be passed to sql query directly as it is moment object, it should be converted to string (and rely on SQL automatic conversion from string/nvarchar to datetime) or should I save it as moment().toDate() ?
Ask yourself what kind of benefits you or anyone that may use you API will gain from getting agnostic Date objects from your DB rather then just plain strictly formatted strings?

Concatenate date and time string into mongo date object

I am sending two fields from client side date and time.
date will be in the format of YYYY-MM-DD i.e 2016-11-08 and time will be in the format of 05:30 PM or 09:45 AM.
I want to combine these two fields and create new field say added_datetime , this field going to be inserted inside MongoDB, so I want it to be in the form of Mongo Date Object so that I can use it for searching with date.
Tried some random things using moments.js but unable to get what I want.
As mentioned in a similiar question you can create a date object with
var date = new Date(datestring);
The code
var startDate = new Date("1900-1-1 8:20:00 PM");
which the original questioner supplied works in chrome and should also work in node since it's the same js engine. This seems to answer your question.
You can find more on dates in the MDN documentation and MongoDB documentation.

How can I convert my normal timestamp into a BSON timestamp?

I am using https://www.npmjs.com/package/mongodb
mongodb has turned my timestamp into BSON (I know this is normal)
my timestamp is this 641912491 where as in the database it looks like this 1457904327000.000000.
I have a document with a key named date_in_the_past which holds my timestamp in it's BSON form.
Note: I am fully aware that the mongodb _id key holds a date but it is of no use to me in this scenario as, that would be the date when the document was written to the db (not the date in the past that I am looking for)
How can I convert my normal timestamp into a BSON timestamp?
I have tried to understand mongodb/js-bson and mongodb/js-bson/blob/master/lib/bson/timestamp.js but I can't see how to do it.
example of what I am looking to do:
var past=timestampToBSON(641912491);
db.collection('docs').find({date_in_the_past:past}).limit(1).toArray(function(e,r){});
If it's stored as a bson timestamp object, you could do something like this
var Timestamp = require('mongodb').Timestamp;
var past = Timestamp(641912491,1);
db.collection('docs').find({date_in_the_past:past})
or
db.collection('docs').find({date_in_the_past: Timestamp(641912491,1)})
it has some more info and examples about it here
https://docs.mongodb.org/manual/reference/bson-types/#timestamps

Categories