Storing ISODates in Collections and searching by date range

7,769 views
Skip to first unread message

Joshua Ellis

unread,
Jun 5, 2013, 5:24:44 AM6/5/13
to meteo...@googlegroups.com
Hi y'all,

I'm trying to figure out what I'm doing wrong here and I'm stumped. I'm building a scheduling app that needs to check and see if there are any appointments set between a certain time of day and the beginning of the next day. I'm storing the appointments in my Collection like so:

{"_id":"3Dg36eg2pvkCS3nBy","startTime":"2013-06-06T16:00:00.000Z"}

As you can see, the 'startTime' field is in ISODate format. However, when I do this, as recommended in the MongoDB manual:

Appointments.find({"startTime":{$gte:"2013-06-06T17:00:00.000Z",$lt:Date.today().addDays(2).toISOString()}})

It returns all my Appointments. (I'm using Date.js, and I've verified that object comes back correctly.)

So what am I doing wrong? Am I setting the startTime as a string, not an ISODate object? If so, how do I a) insert that field as an ISODate and b) query for it properly with $gte and $lt?

Thanks!

Daniel Dornhardt - Daniel Dornhardt Development

unread,
Jun 5, 2013, 5:39:50 AM6/5/13
to meteo...@googlegroups.com
Hello, shouldn't you be using javascript dates instead of date strings? I thought that mongo / EJSON would convert this stuff for you into the appropriate format.

I am using XDate (http://arshaw.com/xdate/) (and then .toDate() at the end again to get the date) to work with javascript dates comfortably.

But just in general, did you try using native JS Dates instead of strings?

Or do you have a link to some examples which show a different wat of going on about things?

Actually, the more I think about it, I'm pretty sure that MongoDB will store your strings as strings and that the comparison ($lt/$gte) can be at best a string comparison, which probably won't do what you want.

Best wishes

Daniel

Daniel Dornhardt, Daniel Dornhardt Development
+49 152 - 56 17 22 61


--
You received this message because you are subscribed to the Google Groups "meteor-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to meteor-talk...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

steeve

unread,
Jun 5, 2013, 7:34:26 AM6/5/13
to meteo...@googlegroups.com
I am storing my dates like this on say an insert.
  updated_td: new Date()

and it stores it as this in Mongo
  updated_td : ISODate("2013-05-28T01:29:51.282Z")

Then you can use gt, gte, lt, lte fairly easily.  I am using Moment though to modify the dates. 

Erick Cardenas-Mendez

unread,
Jun 5, 2013, 8:02:11 AM6/5/13
to meteo...@googlegroups.com
I believe that Daniel is correct and that you are not storing Dates, but just Strings.

So you would really should be storing your dates like this:

{"_id":"3Dg36eg2pvkCS3nBy","startTime": new Date("2013-06-06T16:00:00.000Z")}

BUT you should be aware that the ISO-formatted dates are only properly parsed in browsers that correctly implement ECMAScript 5. Here's some alternate formats:

new Date("Thu June 6 2013 16:00:00 GMT-0700")

new Date(2013, 5, 6, 16, 0, 0)     // same datetime, in the local time zone (the month is zero-indexed)

new Date(Date.UTC(2013, 5, 6, 16, 0, 0))   // same datetime, but in the GMT time zone

Erick Cardenas-Mendez
www.playlistparty.net (built with Meteor)



--

Joshua Ellis

unread,
Jun 5, 2013, 5:09:48 PM6/5/13
to meteo...@googlegroups.com
OK, this is interesting: if I insert the date as new Date(thedate), it stores properly as an ISODate in Mongo. However, if I search the date like so, it fails (I'm using mrt mongo to do it in the database): 

db.appointments.find({startDate: {$gt: "2013-06-05T05:00:00Z", $lt: "2013-06-06T00:00:00Z"}})

It just treats the date as a string. But if I do this, it returns the proper objects:

db.appointments.find({startDate: {$gt: ISODate("2013-06-05T05:00:00Z"), $lt: ISODate("2013-06-06T00:00:00Z")}})

However, when I try to do that from Meteor, it gives me:

Uncaught ReferenceError: ISODate is not defined 

And if I put ISODate in quotes, i.e.

db.appointments.find({startDate: {$gt: "ISODate('2013-06-05T05:00:00Z')", $lt: 'ISODate("2013-06-06T00:00:00Z")'}})

it treats it as a literal string.

Nothing seems to work properly -- no variation I've tried.

Sigh.

Jan Hendrik Mangold

unread,
Jun 5, 2013, 5:50:26 PM6/5/13
to meteo...@googlegroups.com
Joshua

are you trying to search on the client? it uses minimongo which has limitations and not the full mongo implementation. Looks like date handling is one them ... 

Joshua Ellis

unread,
Jun 5, 2013, 5:53:02 PM6/5/13
to meteo...@googlegroups.com
Ooooh, yeah, hadn't thought of the mini mongo issue. Will try a
server-side Meteor.call function. Thanks!

David Glasser

unread,
Jun 5, 2013, 7:03:53 PM6/5/13
to meteo...@googlegroups.com

No, that's not the problem. The issue is that in meteor we standardize on JS Dates everywhere, so you should pass them to find too.

--

mohamed elmesseiry

unread,
Mar 24, 2014, 5:37:52 PM3/24/14
to meteo...@googlegroups.com
i was running into the same situation in Meteor trying to generate the query in a string object then fill it in find command but it didnt work.

when i did this it worked find.
while Alarms is my collection name in Meteor

dataObj = Alarms.find({timestamp: {$gte: new Date(start) , $lt: new Date(end) }}).fetch()
Reply all
Reply to author
Forward
0 new messages