ISODate in json response

3,939 views
Skip to first unread message

Gunners

unread,
Jun 2, 2011, 7:35:07 PM6/2/11
to mongodb-user
Here is a quick overview of what we have set-up..

We have a script written in ruby, which periodically does the
following two things on the primary node.
resp = `mongo --quiet --eval 'printjson(rs.status())'`
JSON.parse(resp)

This response is then used for logs and few other things.. This script
recently stopped working when we transitioned from mongo 1.6.5 to
1.8.1.. Turns out that with 1.8.1, the response of
printjson(rs.status()) call was not pure json but contained dates in
the format of ISODate("xxxxxx")... Thus the call to JSON.parse
returned with a ParserError exception.

I was wondering what would be right way to tackle this error.

Should I parse the response and remove references to ISODate?
Should I use bson library instead of using printjson?
Something I am missing?

Thanks.


Bernie Hackett

unread,
Jun 2, 2011, 9:55:15 PM6/2/11
to mongodb-user
Why not just run the command "replSetGetStatus" using the command
method of the Database class in Ruby? No JSON.parse required. All the
mongo shell does is run that command:

repl0:PRIMARY> rs.status
function () {
return db._adminCommand("replSetGetStatus");

CharlieDigital

unread,
Jul 5, 2011, 3:05:47 PM7/5/11
to mongodb-user
I have a similar question as I'm considering architecting my solution
to write the serialized BSON (via BsonDocument.ToJson()) to a web
page.

Of course, the problem with this is that it produces the
ISODate("...") and ObjectId("...") as a part of the JSON response,
which obviously has no implementation on the client and causes an
error.

So I wonder if there is a default script file that contains an
implementation of these functions somewhere that can be included in
the page? Is there an alternative way to serialize the objects to a
JSON string that will produce an object without these function calls?

I've tried the JavaScriptSerializer from
System.Web.Script.Serialization. The problem with this approach is
that it does not include the type discriminator for inherited types
whereas BsonDocument.ToJson() does include this as (by default) a
field "_t".

Other thoughts on the proper way to server the JSON to the browser in
a way that can be processed by the client runtime?



On Jun 2, 9:55 pm, Bernie Hackett <ber...@10gen.com> wrote:
> Why not just run the command "replSetGetStatus" using the command
> method of the Database class in Ruby? NoJSON.parse required. All the
> mongo shell does is run that command:
>
> repl0:PRIMARY> rs.status
> function () {
>     return db._adminCommand("replSetGetStatus");
>
> }
>
> On Jun 2, 4:35 pm, Gunners <naren.chain...@gmail.com> wrote:
>
>
>
>
>
>
>
> > Here is a quick overview of what we have set-up..
>
> > We have a script written in ruby, which periodically does the
> > following two things on the primary node.
> > resp =  `mongo --quiet --eval 'printjson(rs.status())'`
> >JSON.parse(resp)
>
> > This response is then used for logs and few other things.. This script
> > recently stopped working when we transitioned from mongo 1.6.5 to
> > 1.8.1.. Turns out that with 1.8.1, the response of
> > printjson(rs.status()) call was not purejsonbut contained dates in
> > the format ofISODate("xxxxxx")... Thus the call toJSON.parse

Robert Stam

unread,
Jul 5, 2011, 3:16:41 PM7/5/11
to mongodb-user
Are you using the C# driver? (I'm guessing you are based on the class
names you mentioned).

If so, you can set the JsonOutputMode to something other than the
default value, like this:

var settings = new JsonWriterSettings { OutputMode =
JsonOutputMode.JavaScript };
var json = document.ToJson(settings);

These are the JsonOutputModes availabe (the default is Shell):

public enum JsonOutputMode {
/// <summary>
/// Output strict JSON.
/// </summary>
Strict,
/// <summary>
/// Use JavaScript data types for some values.
/// </summary>
JavaScript,
/// <summary>
/// Use JavaScript and 10gen data types for some values.
/// </summary>
TenGen,
/// <summary>
/// Use a format that can be pasted in to the MongoDB shell.
/// </summary>
Shell

CharlieDigital

unread,
Jul 5, 2011, 3:41:39 PM7/5/11
to mongodb-user
Robert,

Yes, C#. Your input definitely helps. This is pretty much what I was
looking for (though the date comes across as a string instead of a
Date object -- just a note to anyone else following this)

Thanks!

-- Chuck

On Jul 5, 3:16 pm, Robert Stam <rstam10...@gmail.com> wrote:
> Are you using the C# driver? (I'm guessing you are based on the class
> names you mentioned).
>
> If so, you can set the JsonOutputMode to something other than the
> default value, like this:
>
>     var settings = new JsonWriterSettings { OutputMode =
> JsonOutputMode.JavaScript };
>     varjson= document.ToJson(settings);
> >JSONstring that will produce an object without these function calls?
>
> > I've tried the JavaScriptSerializer from
> > System.Web.Script.Serialization.  The problem with this approach is
> > that it does not include the type discriminator for inherited types
> > whereas BsonDocument.ToJson() does include this as (by default) a
> > field "_t".
>
> > Other thoughts on the proper way to server theJSONto the browser in

Robert Stam

unread,
Jul 5, 2011, 3:45:17 PM7/5/11
to mongodb-user
Not sure what you mean by "the date comes across as a string instead
of a Date object".

Is there a bug that needs to be fixed?

CharlieDigital

unread,
Jul 5, 2011, 3:48:37 PM7/5/11
to mongodb-user
Robert,

One interesting observation is that the date seems to be off.

Serializing directly to JSON (without the settings), I get the
following value for a date field:

ISODate("2011-07-04T19:00:08.897Z")

With the settings, if I serialize to JSON using the settings you
recommended, I get the following value:

Date(1309806008897)

When I access the field, via obj.MyDateField, I get a string back in
the browser client:

"Tue Jul 5 15:42:40 EDT 2011"

This clearly doesn't match up. So am I missing something here with
regards to handling the dates?

-- Chuck

I am in the Eastern time zone in the US, but I'm not sure how the
minutes and seconds got

On Jul 5, 3:41 pm, CharlieDigital <chen.charle...@gmail.com> wrote:

CharlieDigital

unread,
Jul 5, 2011, 3:52:03 PM7/5/11
to mongodb-user
Robert, the value is returned as -- for example:

var obj = {Created: Date(1309806008897)};

Calling obj.Created.getFullYear() fails because obj.Created is not a
Date object.

I tested by using

alert(typeof obj.Created) and it returns "string".

Don't know if that is the intent or if the intent is:

{Created: new Date(...)}

-- Chuck

Robert Stam

unread,
Jul 5, 2011, 3:56:34 PM7/5/11
to mongodb-user
You are right, the output should have been "new Date(1309806008897)".
The "new" is required because JavaScript's Date function is one of its
most broken features!

I will change the driver to output "new".

CharlieDigital

unread,
Jul 5, 2011, 4:16:14 PM7/5/11
to mongodb-user
Robert,

Pay no attention to my other message; it's purely because of the
missing "new" statement in the serialized JSON when using
JsonOutputMode.JavaScript.

It seems that invoking Date(1309806008897) (or whatever other numeric
value) always results in the current date being returned as a string.

So adding "new" should fix that.

-- Chuck

Robert Stam

unread,
Jul 5, 2011, 4:25:19 PM7/5/11
to mongodb-user
I created a JIRA ticket for the missing "new" for Date values:

https://jira.mongodb.org/browse/CSHARP-262

Will fix it right away.

Robert Stam

unread,
Jul 5, 2011, 4:32:55 PM7/5/11
to mongodb-user
One potential issue with adding "new" is that it conflicts with the
BSON standard for "Extended JSON":

http://www.mongodb.org/display/DOCS/Mongo+Extended+JSON

Probably the spec for Extended JSON should be changed to include the
"new" also.
Reply all
Reply to author
Forward
0 new messages