Databases

Intro to Databases

What is a database?

  • A collection of information/data
  • Has an interface to manipulate

SQL (relational) vs. NoSQL (non-relational)

Relational Database

  • Need to define structure ahead of time
  • Structure: multiple tabales, rigid

Non-relational Database

  • No need to define structure ahead of time
  • Structure: nested, flexible

Example: Relational Database

USERS TABLE

id name age city favFood
1 Ira 24 Missoula null
2 Tammy 34 NYC Ribeye

COMMENTS TABLE

id text
1 "lol"
2 "Come visit Montana!"
3 "I love purples"
4 "Seriously Montana is great!"

USER/COMMENTS JOIN TABLE

userId commentId
1 2
1 4
2 1
2 4

Example: Non-Relational Database

BJON: Binary Javascript Object Notation

{
  name: "Ira",
  age: 24,
  city: Missoula,
  comments:[
    {text: "Come visit Montana!"},
    {text: "Seriously Montana is great!"}
  ]
}

{
  name: "Tammy",
  age: 34,
  city: NYC,
  comments:[
    {text: "lol"},
    {text: "Seriously Montana is great!"}
  ],
  favFood: "Ribeye"
}

Intro to MongoDB

  • What is MongoDB?
    • A non-relational database
  • Why are we using it?
    • Most popular NoSQL database with node and express
    • MEAN stack: Mongo, Express, Angular, Node

Mongo Shell Basics

Common Commands

Command Description
mongod Starts the mongo deamon running in the background
mongo Opens up the mongo shell (need to start mongod first)
help Help
show dbs Show database names. Won't show if database is empty
show collections Show collections within a database
use [database] Set current database to work with. Create if not exist
db.[collectionName].drop Delete all records in a collection of a database

CRUD in Mongo Shell

Create, Read, Update, Destroy commands

insert

  • Insert object into collection of a database
db.dogs.insert({name:"Rusty", breed: "Mutt"})
// WriteResult({"nInserted: 1})

find

  • List object(s) in a collection
// view all dogs in database
  db.dogs.find()

// view detail
  db.dogs.find({name: "Rusty"})

update

  • Takes 2 arguments: id and update Info
  • Will overwrite existing info
db.dogs.update({name: "Lulu"}, {breed: Labradoodle})

// Use $set to preserve existing object details
db.dogs.update({name: "Rusty"}, {$set: {name: "Tater", isCute: true}})

remove

// Remove all Labradoodle
db.dogs.remove({breed: "Labradoodle"})

// Remove only 1 match
db.dogs.remove({breed: "Mutt"}).limit(1)

Mongoose

What Is Mongoose?

  • An ODM (Object Data Mapper) in JS on top of Mongo DB
  • A package that helps us to interact with mongo db inside a js file
  • Just like jQuery helps us to interact with the DOM

Why are we using it?

  • To interact with a Mongo Database using Mongoose

Install and configure Mongoose

First be sure you have MongoDB and Node.js installed. Make sure that ./mongod is running in the background

npm insall mongoose --save

The first thing we need to do is include mongoose in our project and open a connection to the database a running instance of MongoDB.

var mongoose = require('mongoose');

// Connect and create (if not exist) database
mongoose.connect("mongodb://localhost/yelp_camp", {useMongoClient: true});

Setup Schema

With Mongoose, everything is derived from a Schema

// Will be broken up into separate files later (see v3)
var campgroundSchema = new mongoose.Schema({
  name: String,
  image: String,
  description: String
});

Compile Schema into Model

The next step is compiling our schema into a Model. A model is a class with which we construct documents. In this case, each document will be a campground with properties and behaviors as declared in our schema.

// Capitalize "Campground" to indicate a class
var Campground = mongoose.model("Campground", campgroundSchema);

Using Model with Routes

INDEX route

To show all elements in a Model

// Syntax
Model.find({}, callback);
app.get("/campgrounds", function(req, res){
  //Get all campgrounds from DB
  Campground.find({}, function(err, allCampgrounds){
    if (err){
      console.log(err);
    } else {
      //name reference to ejs:callback function
      res.render("index", {campgrounds:allCampgrounds});
    }
  });
});

CREATE route

To insert new element

// Syntax
Model.create({}, callback);

If the verb is a POST and you are using bodyParser, then you should be able to get the form body in you function with req.body. That will be the parsed JS version of the POSTed form.

// Need 2 routes to send a POST request:
// one to show the form and a form to submit somewhere i.e. CREATE route

app.post("/campgrounds", function(req, res){
  //get data from form and add to campgrounds array
  var name = req.body.name;
  var image = req.body.image;
  var desc = req.body.description;
  var newCampground = {name:name, image:image, description:desc};

    //Create a new campground and save to database
  Campground.create(newCampground, function(err, campground){
    if (err){
      console.log(err);
    } else {
      //redirect back to campgrounds page
      res.redirect("/campgrounds");
    }
  });
});

NEW route

To create new items

app.get("/campgrounds/new", function(req, res){
  res.render("new.ejs");
});

SHOW route

Show more info about the element. MUST be put after NEW route Express function req.params will return parameters in the matched route. If your route is /campgrounds/:id and you make a request to /campgrounds/5 - req.params would yield {id: "5"}

// Syntax
Model.findById(id, callback);
app.get("/campgrounds/:id", function(req, res){
  Campground.findById(req.params.id).populate("comments").exec(function(err, foundCampground){
    if (err) {
      console.log(err);
    } else {
      console.log(foundCampground);
      //render show template with that campground
      res.render("show", {campground: foundCampground});
    }
  });
});

Refactor Mongoose Code (277)

Create a models directory (CLI)

mkdir models
touch models/campground.js

In file campground.js:

var mongoose = require("mongoose");

// Optional: {usePushEach: true}
var campgroundSchema = new mongoose.Schema({
    // Put your schema details here
}, {usePushEach: true});

module.exports = mongoose.model("Campground", campgroundSchema);

In file app.js:

var Campground = require(./models/campground);

Require everything correctly

  • in app.js