C# driver - cannot query date fields

5,668 views
Skip to first unread message

Chris

unread,
May 7, 2011, 4:47:51 AM5/7/11
to mongodb-user
Hello,

I use the C# driver to insert records from one process. A different
process uses the C# driver to perform map/reduce operations. When
filtering records based on a datetime field, the second process
creates query documents that format datetime values strangely and do
not match records in my server.

First C# process:
Values = new BsonDocument();
Values.Add("start", DateTime.Now);

MongoDB shell:
> db.CollectionName.findOne()
{
....
"start" : ISODate("2011-05-04T13:20:06.978Z")
}

Second C# process:
DateTime queryTime= DateTime.Parse(begin);
query = Query.GTE("start", beginTime)
Console.WriteLine(query.ToString())
// Displays: { "start" : { "$gte" : { "$date" :
1303790400000 } } }

My questions are:

1. Why do the dates I insert end up as ISODate? Is this a recent
change?

2. Why does my query document use $date instead of Date() or ISODate()
to represent my query?

3. How can I make the query document format date fields the same way
they appear in my collection? I have tried making the query value be
a literal string containing my desired typing
("ISODate('2000-01-01T00:00:01Z"), as well as constructing a literal
BsonDocument representing this same query with my desired typing and
using it instead. Neither approach worked.

Thank you,
Chris

Client: Windows XP SP3
C# driver: 1.0.0.4098
Server: Windows 2003 Server SP2
MongoDB: 1.8.1

Nat

unread,
May 7, 2011, 10:24:31 AM5/7/11
to mongod...@googlegroups.com
1. Yes. That's a new change in 1.8 to make a distinction between string and date
2. $date is just a strict(and old) json representation of date. You can take a look at http://www.mongodb.org/display/DOCS/Mongo+Extended+JSON
3. You don't have to. It's just C# formats json in strict format. You just use .NET DateTime to refer to it. That would be good enough. If you want to be strict, you can specify DateTime with DateTimeKind.UTC
--
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To post to this group, send email to mongod...@googlegroups.com.
To unsubscribe from this group, send email to mongodb-user...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mongodb-user?hl=en.

Chris

unread,
May 7, 2011, 1:59:42 PM5/7/11
to mongodb-user
I should be more clear. The query documents I build using the C#
driver don't work. I can build queries, but they don't return the
correct records. If I use this command the query returns no data.

DateTime beginTime = DateTime.Parse("2011-04-26");
query = Query.GTE("start", beginTime)
Console.WriteLine(query.ToString())
// Displays: { "start" : { "$gte" : { "$date" :
1303790400000 } } }

If I take this query document, modify it by hand to use ISODate, and
execute it in the shell, it returns the documents I expect.

> db.CollectionName.find({ "start" : { "$gte" :
ISODate("2011-04-26")} })

What am I doing wrong?

Robert Stam

unread,
May 7, 2011, 2:47:50 PM5/7/11
to mongodb-user
Several important points to keep in mind:

- All dates are stored in UTC in MongoDB
- MongoDB stores dates internally as a 64 bit integer representing
milliseconds since 1970-01-01T00:00:00Z
- If the date value you provide the C# driver is not already in UTC it
will be converted to UTC before being stored in MongoDB
- There is no actual data type called ISODate, that is just the way
the shell displays dates (in more recent versions anyway)
- Before ISODate was introduced dates were displayed as { $date :
somereallybigintegerthatmeansnothingtohumas }
- In the latest versions of the C# driver (but post v1.0) ToJson now
also uses the new ISODate display format

I see in your first posting that you are using DateTime.Now, so the
value is going to be converted to UTC as it is stored in the database.
Consider using DateTime.UtcNow.

For the question in your second post, I recommend not using
DateTime.Parse. You get into all sorts of issues with time zones and
cultural conventions regarding how DateTimes are formatted. Instead
just use the DateTime constructors, being careful to use UTC or else
to carefully take timezone conversions into account. I would write
your query as:

var beginTime = new DateTime(2011, 4, 26, 0, 0, 0, DateTimeKind.Utc);
var query = Query.GTE("start", beginTime);

but you also have to make sure you used UTC when you inserted the
documents.

If you still have problems you could provide a sample document as
output by the mongo shell and also let us know what timezone you are
in.
Reply all
Reply to author
Forward
0 new messages