Search code examples
javascriptjsonnode.jsmongodbnode-mongodb-native

Is there a way to represent ISODate and ObjectID fields in JSON that MongoDB will recognize?


I am trying to import a JSON file into MongoDB inside node. Here is what I am trying to do:

db.open(function(err, db) {
  if(!err) {
    db.collection('orgs', {safe: true}, function(err, collection) {
      if (err) {
        console.log("The 'orgs' collection doesn't exist. Creating it with sample data...");
        db.collection('orgs', function(err, collection) {
          orgs = require("../data/orgs.json");
          collection.insert(orgs, {safe:true}, function(err, result) {});
        });
      }
    });
  }
});

Note that NodeJS can import JSON automatically as JSON, which is nice, but JSON does not handle objects like ISODate or ObjectID. Here is a snippit of the JSON data I am trying to import:

./data/orgs.json:

  {
    "stub": "apple",
    "name":"Apple, Inc.",
    "timezone": "America/New_York",
    "currency": "USD",
    "plans": [
      {"planId":1, "dtStart": {"$date":"2012-12-07 12:34:56"}},
      {"planId":0, "dtStart": {"$date":"2012-12-05 23:45:02"}, "dtEnd": {"$date":"2012-12-07 12:34:56"}}
    ]
  }

I am using the mongodb native driver for Node.

I tried to use integer representation of the date, but it did not work.

Is there a way to represent ISODate and ObjectID fields in JSON that MongoDB will recognize?


Solution

  • You can't store dates and other custom objects in JSON, since in supports only Strings, Numbers, Booleans and null's. So, to load them from JSON you shall somehow restore them from their string representation. Of course, you can use BSON instead of JSON since it supports all this data types, but there is a better way to solve your problem.

    Since your already using require instead of JSON.parse to load and parse your JSON data, you can make one more step and use JavaScript representation of your data instead of pure JSON:

    var ObjectID = require('mongodb').ObjectID;
    
    module.exports = {
      stub: "apple",
      name: "Apple, Inc.",
      timezone: "America/New_York",
      currency: "USD",
      plans: [
        {
          planId: new ObjectID("1"),
          dtStart: new Date("2012-12-07 12:34:56")
        },
        { 
          planId: new ObjectID("0"),
          dtStart: new Date("2012-12-05 23:45:02"),
          dtEnd: new Date("2012-12-07 12:34:56")
        }
      ]
    }
    

    In this case you'll be able to use new Date and new ObjectID to create dates and object ids.

    N.B. You can use require('bson').ObjectID instead of require('mongodb').ObjectID, the result will be the same.