MongoDB: https://mongodb.org/
To install MongoDB, we need to install it and create a folder for the database. We've provided an automated install script here: https://github.com/ga-chicago/MongoDBInstallScript/
Annotated version of the script
echo -e "*** Hi! This script will install MongoDB."
echo -e "You could be asked for your admin password up to four times."
# update homebrew
brew update
# use homebrew to install
echo -e "Installing MongoDB"
sudo brew install mongodb -Y
# create the mongodb swap directory
echo -e "Creating the MongoDB directory..."
sudo mkdir -p /data/db
# set read/write permissions for this directory to root
echo -e "Setting Permissions to the /data/* directory for MongoDB"
sudo chmod -777 /data/*
# start mongodb!
echo -e "Starting Mongod..."
sudo mongod
If you run into any problems during installation, please refer to this document: http://docs.mongodb.org/manual/tutorial/install-mongodb-on-os-x/
To start mongodb, simply run the following command: sudo mongod
. Use CTRL-C to stop the service.
Mongoose connects our application to our MongoDB database. To add it as a dependancy to our project, we just need to install it as follows:
npm install mongoose --save
Now, create a new folder in your project called models
. Then, create a file called db.js
-- this is where we're going to store our database specific files. No actual models will be in this file. Inside of our db.js
file, we're going to require Mongoose:
var mongoose = require('mongoose');
Connect to Mongo using Mongoose
// mongodb://username:password@localhost:27027/database-name
var connectionString = 'mongodb://localhost/test';
// connect to database
mongoose.connect(connectionString);
These events tell us the status of our connection to MongoDB; this are VITAL to debugging.
Example
mongoose.connection.on('connected', function () {
console.log('Mongoose connected to ' + connectionString);
});
mongoose.connection.on('error',function (error) {
console.log('Mongoose connection error: ' + error);
});
mongoose.connection.on('disconnected', function () {
console.log('Mongoose disconnected!');
});
In your primary app.js
file, we need to include our /models/db.js
file. This will establish our connection to our database.
app.js
// include mongodb via /models/db.js
require('./models/db');
MongoDB stores data in each database as documents. These documents are stored as BSON; this is just binary JSON data. The tool that we're using to communicate with Mongo - mongoose takes this BSON data and turns it into JSON for our ease of use. One of the primary advantages of using MongoDB with Javascript is that everything is essentially a Javascript object!
Each time you create a document in MongoDB, it is given an
_id
. MongoDB automatically creates this when each document is created and assigns it a unique ObjectId value. It can be considered the primary key of your Document.
MongoDB allows the following schema types inside of a document
:
_id
)Let's create a new file: /models/tasks.js
; the following Schema will be placed inside of there.
We now need to model some data. For example, say we have a list of tasks we'd like to complete. We're going to store our tasks as documents in MongoDB. A task as a Javascript object would look like:
var task = {
name: "My task",
description: "This is something I need to do",
completed: false
};
We can use the mongoose.Schema({});
method to create a schema.
// require mongoose
var mongoose = require('mongoose');
var TaskSchema = new mongoose.Schema({
name: String,
description: String,
completed: Boolean
});
Notice how we're declaring the type of data stored in the object. Say we want to have a default value, though. When you create a task, it is not completed yet, no?
// require mongoose
var mongoose = require('mongoose');
var TaskSchema = new mongoose.Schema({
name: String,
description: String,
completed: {type: Boolean, "default": false }
});
// export our Model for use in our node app// export!
module.exports = mongoose.model('Task', TaskSchema);
We put the word default
in quotes because it is a reserved word in Javascript. All we've changed is adding a default
value as well as specifying a type
(based on what is allowed in the Schema).
Finally, to make our actual MVC-esque model, we need to tell Mongoose to create a model:
var Task = mongoose.model('Task', TaskSchema);
Where we declare Task
as the new model name and assign a schema to this model.
find
: General search based on a supplied query objectfindById
: Look for a specific IDfindOne
: Get the first document to match the supplied querygeoNear
: Find places geographically close to the provided latitude and longitudegeoSearch
: Add query functionality to a geoNear operationvar mongoose = require('mongoose');
var Task = require('../models/Tasks');
// get ALL items in an array
Task.find(function (err, tasks) {
console.log(tasks)
});
// create an item
Task.create({ name: "task #1", description: "a simple task"}, function (err, task) {
console.log(task);
});
// get a specific item by _id
Task.findById(id, function (err, task) {
console.log(task);
});
// update a task by _id
Task.findByIdAndUpdate(id, { description: "updating this" }, function (err, task) {
console.log(task);
});
// delete by _id
Task.findByIdAndRemove(id, { params: "object stuff" }, function (err, task) {
console.log("Deleted:");
console.log(task);
});
In app.js
we need to include additional files and dependencies. We also need to create a routes/tasks.js
file to include. Go ahead and do that now.
In app.js, add the following:
// require additional modules
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
// require mongodb & model
require('./models/db'); // db
require('./models/Tasks'); // model
// include route files in /routes
var routes = require('./routes/index');
var tasks = require('./routes/tasks');
// start express app
var app = express();
// we need to parse req.body.. so we add parsers
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(require('less-middleware')(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
// define our http routes and bind those routes to routes in /routes
app.use('/', routes); // localhost:5000/
app.use('/api/tasks/', tasks); // localhost:500/api/tasks
Our /routes/tasks.js file will look just like this:
var express = require('express');
var router = express.Router();
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var Task = require('../models/Tasks');
/* GET /api/tasks listing. */
router.get('/', function(req, res, next) {
console.log(req.body);
Task.find(function (err, tasks) {
if (err) return next(err);
res.json(tasks);
});
});
/* POST /api/tasks */
router.post('/', function(req, res, next) {
console.log(req.body);
Task.create(req.body, function (err, task) {
if (err) return next(err);
res.json(task);
});
});
/* GET /tasks/id */
// http://localhost:5000/api/tasks/5566a21e1e3a211aa1c63495
router.get('/:id', function(req, res, next) {
Task.findById(req.params.id, function (err, task) {
if (err) return next(err);
res.json(task);
});
});
/* PUT /tasks/:id */
router.put('/:id', function(req, res, next) {
console.log(req.body);
Task.findByIdAndUpdate(req.params.id, req.body, function (err, task) {
if (err) return next(err);
res.json(task);
});
});
/* PATCH /tasks/:id */
router.patch('/:id', function(req, res, next) {
console.log(req.body);
Task.findByIdAndUpdate(req.params.id, req.body, function (err, task) {
if (err) return next(err);
res.json(task);
});
});
/* DELETE /tasks/:id */
router.delete('/:id', function(req, res, next) {
console.log(req.body);
Task.findByIdAndRemove(req.params.id, req.body, function (err, task) {
if (err) return next(err);
res.json(task);
});
});
module.exports = router;