Week 5 - Databases and MongoDB

Database - long term memory. Discuss data modelling, saving and retrieving data. Getting started with MongoDB on Heroku with AddOns.


Github Code
http://itpdwdexpresstemplates.herokuapp.com/


Databases

Databases allow you to create, retrieve, update and delete data (CRUD). Commonly web applications use a database to display content submitted by the site editors or collect information from users via a form.

Database come in a few flavors

Getting started with MongoDB on Heroku

We will be using MongoLabs as our MongoDB host service, they have a free starter plan that we can easily associate with our Heroku accounts. When we have added the MongoLabs service we will have a connection string that includes username, password and URI to the database server.

Step 1 : Adding MongoLabs to your Heroku App

  • Verify your Heroku account to start using the Add-on services, http://www.heroku.com/verify.
  • Navigate to the code folder in Terminal and run the following command.

    heroku addons:add mongolab:starter
    

Step 2: Get the MongoLabs URI to your database

  • Next, we need to get the username, password and database URI that MongoLabs has supplied us. Heroku keeps this in the a configuration file.

Get your Monglab URI, run the following command in Terminal

heroku config --shell | grep MONGOLAB_URI >> .env

See all Heroku config variable

heroku config

Step 3: Verify environment configuration file (.env)

The .env file will store the MongoLabs URI which includes your username and password. The contents of .env will be available in your code as environment variables.

MONGOLAB_URI=mongodb://username:password@host:port/database

If your file looks different, try the steps above again. Save the .env file after updated.

You can access environment variables in your NodeJS code, for example in web.js as follows,

process.env.MONGOLAB_URI 
// this is the same as manually coding 'mongodb://username:password@host:port/database'

Step 4: Verify contents .gitignore file

If the .gitignore file does not exist, create it. Place the following text inside and save.

node_modules
.env

Include Mongo Modules in Package.json

We will use MongooseJS to connect and query our MongoLab database. Let's add to MongooseJS to our package.json

package.json (dependencies section)

...
"dependencies": {
    "express": "3.0.0rc5",
    "hogan-express" : "0.3.3",
    "moment" : "1.7.2",
    "mongoose" : "3.5.4"
},
...

Install new modules with

npm install

Connect app.js to database

Require Mongoose at the top of your app.js file

var mongoose = require('mongoose');

Inside the app.configure callback function, add or uncomment the line

app.db = mongoose.connect(process.env.MONGOLAB_URI);

app.db will use Mongoose to connect to the MongoLab URI inside our .env file

NOTE: process.env is declared and initialized by foreman. That's why we use foreman start or an alternative of foreman to start our applications.

Define your data schema

MongoDB Documents

MongoDB stores data in documents. The data is shape is defined with Schemas using Mongoose. All Mongo documents store in BSON format, which is very similar for to JSON for most purposes.

Mongoose Guide

The Mongoose guide is the best place to start to understand how to set up and query your data.

Schemas and Models -

Schemas define what shape your data will take, very much like a JavaScript object Mongoose Schema allows you to define fields and their data types, strings, booleans, arrays, dates, etc.

There is a new file called /models/astronaut.js, this includes the data definitions or schema for your database. You will define what data you will be saving in your Mongo collection. See the Mongoose web site for more information, http://mongoosejs.com/

models/astronaut.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

// define a new schema
var AstronautSchema = new Schema({
    slug : { type: String, lowercase: true, unique: true },
    name : String,
    birthdate : Date,
    missions : [String],
    photo : String,
    source : {
        name : String,
        url : String
    },
    skills : [String],
    walkedOnMoon : Boolean,

    lastupdated : { type: Date, default: Date.now }
});

// export 'Astronaut' model
module.exports = mongoose.model('Astronaut',AstronautSchema);

Models are the constructor of a Schema. Models are used to create, retrieve, update and delete data.

Inserting new data

Mongoose Docs http://mongoosejs.com/docs/models.html

Create a new astronaut document from the astronaut model.

var astronautModel = require('../models/astronaut.js');
var astroData = {
    name : 'John Schimmel',
    skills : ['floating','repairing satellites'],
    walkedOnMoon : false
};
var newAstro = new astronautModel(astroData); // new astronaut document
newAstro.save(); //save to database

Querying data

Retrieve your data, http://mongoosejs.com/docs/queries.html

var astronautModel = require('../models/astronaut.js');

var filter = {}; // no filter
var fields = 'name slug birthdate'

astronautModel.find(filter, fields, function(err, astronauts){
    if (err) {
        console.error('uhoh something went wrong');
        console.error(err);
    }
    if (astronauts == null) {
        console.log("no astronauts found");
    } else {
        console.log("found " + astronauts.length + " astronauts");

        for(a in astronauts) {
            var currAstro = astronauts[a]; // current looped astronaut
            console.log(currAstro.name + " " + currAstro.birthdate);
        }
    }
})

Query for a specific piece of data

var astronautModel = require('../models/astronaut.js');

var filter = {slug:'john_glenn'}; // filter where slug==john_glenn
astronautModel.findOne(filter, function(err, astronaut){
    if (err) {
        console.error('uhoh something went wrong');
        console.error(err);
    }
    if (astronaut == null) {
        console.log("Could not find your astronaut");
    } else {
        console.log("found your astronaut");
        console.log(astronaut);
    }
})

Open your MongoLab Admin Panel

heroku addons:open mongolab:starter



Assignment

This is a very important week. The rest of the semester builds on our web applications having database access,

  • this week get your Heroku app connected to MongoLab
  • create a Schema for your data inside the /models/yourschema.js file
  • Insert some data using a form POSt
  • Query and display data
  • comments powered by Disqus