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 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.
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,