You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#### Populating referenced collections in MongoDB from JSON files using Node.js and Mongoose
I recently began working with Node and MongoDB for a small personal project, largely just to learn the technologies. One thing that is fairly simple but that I found far from obvious and lacking in concrete examples was how to populate the part of my database that used referenced collections from the sample JSON data I was starting with. This post attempts to fill that gap using the following code snippets, which are heavily commented inline. You will notice I am using the awesome [Mongoose](http://mongoosejs.com/) library which makes working with MongoDB very easy.
// once the connection is established we define our schemas
db.once( 'open', functioncallback() {
// independent schema
var FoodSchema =newSchema( {
name:String,
unit:String,
p:Number,
f:Number,
c:Number
} );
// this schema represents a collection whose documents
// will each hold a reference to a single document
// from the FoodSchema collection
var LogEntrySchema =newSchema( {
date:Date,
qty:Number,
// starting the name with an underscore is simply a convention
// to denote this field as a reference
// the type instructs Mongoose to set this up as a reference
// to another document's _id property, which is automatically
// generated by MongoDB. the ref field refers to the Model name
_food: { type:Schema.Types.ObjectId, ref:'Food' }
} );
// create Mongoose models from our schemas
var Food =mongoose.model( 'Food', FoodSchema );
var LogEntry =mongoose.model( 'LogEntry', LogEntrySchema );
} );
} );
```
During development I simply defined a route that I could load to trigger a database rebuild. This proved very useful as I would regularly muck things up while working on a new form or other piece of the app. Below is the code for (re)populating the database from JSON files.
```javascript
var mongoose =require( 'mongoose' )
, _ =require( 'lodash' )
, foodData =require( './mockdata/foodData.json' )
, logData =require( './mockdata/logData.json' );
exports.reset=function( req, res ) {
// get refs to the models we defined above
var Food =mongoose.model( 'Food' );
var LogEntry =mongoose.model( 'LogEntry' );
// clear all existing documents from the collections
Food.find().remove();
LogEntry.find().remove();
// populate the foods collection from json data
// nothing fancy here as Food documents do not reference anything else
for( var i =0; i <foodData.length; i++ ) {
newFood( foodData[ i ] ).save();
}
// now that the collection is populated we iterate over it
Food.find( function( err, foods ) {
var foodMap = {};
// store _ids of Food documents that Mongo generated upon insert
for( var i =0; i <foods.length; i++ ) {
var food = foods[i];
// I am mapping the ids to the food names because the LogEntry
// JSON data contained this field thanks to the original source
// data's structure (a spreadsheet).
// You could utilize a more sophisticated lookup here if necessary.
foodMap[ food.name ] =food._id;
}
// populate the LogEntries collection from json data
for( i =0; i <logData.length; i++ ) {
var logEntry = logData[ i ];
// we find and store food._id on LogEntry for reference
logEntry._food= foodMap[ logEntry.food_name ];
// note that only the fields defined in the schema will be
// persisted to Mongo, so the foodName field we used for
// lookup will not be unnecessarily added to the db
newLogEntry( logEntry ).save();
}
} );
res.redirect( "/" );
};
```
And there you have it. Far from revolutionary, but hopefully it will help someone get up and running a bit more quickly than I did, though I have to say I was pleasantly surprised with how quickly I was able to be productive with these new (to me) technologies. If you have corrections or suggestions for improvement please leave a comment or fork this Gist.