본문 바로가기
창고 3/[Dev] My Readme

몽고 DB 기초 2

by 부엉이의 정보 창고 2022. 1. 5.
728x90

Schema, Collection, And Model

In creating database, the first thing we need is to create a schema. Each schema maps to a MongoDB collection.

  • Schema => Collection => Model ===(instantiation)===> Document

In MongoDB, a lot of databases can exist. Choose the one that you need and connect it using mongoose. Database is structured as follows

What is schema?
  • Model : a list of concepts describing data(abstract)
  • Schema : a list of attributes and instructions where database engine reads/follows(concrete, physical). Schema is to decide and tell the record what type of property they should have.
const mongoose = require('mongoose') 

// Create a schema
const HumanSchema = moongose.Schema({
    name : {
        type : String, 
        required : true
    }
    age : Number
})

CRUD in MongoDB

Inserting, searching, updating, and deleting are asynchronous actions in database. The 'done' callback function should be called once the asynchronous operations are done.

// done callback convention in Node.js
const doSomething = function (done) { 
    if (err) return done(err)
    done(null, result)
}

Types of Mongoose CRUD methods are as follows(cb : short for callback) :

  • mongoose.Schema
  • mongoose.model
  • document.save
  • model.find(filter, cb) : find all matches
  • model.findOne(filter, cb) : find one match
  • model.findById(filter, cb)
  • model.findAndUpdate(filter, update, new) : set the third argument 'new'. Otherwise it will return unchanged object by default
  • model.findByIdAndRemove(filter, cb)
  • model.remove : delete all matches. returns JSON object, not updated(meaning some records deleted) docs.
  • chain search : making query chains to narrow results.
// query chain search in MongoDB
const queryChain = (done) => { 
    const myKeyword = "sushi"
    Sushi.find(myKeyword)
         .sort( { price : 1 } ) // show expensive sushi first
         .limit(5) // show 5 of them 
         .select( { location : 1} ) // show location 
         .exec(function(err, data) {
             if (err) return console.log(err)
             done(null, data)
         }) // execute queries. If exec method is not provided with the callback, it won't work. 
}

Creating And Saving records

You can create model and save the document(model instance) in database, which is the purpose of creating it.

// Create a model from schema
let Person = mongoose.model('Person', personSchema);

const createAndSavePerson = (done) => {
  // Create a document(model instance)
  const person = new Person( {
    name : "Jake Sung", 
    age : 27, 
    favoriteFoods : ["Pizza, Sushi"]
   })

   // Save the document in database
   person.save(function(err, data) { 
    if (err) return console.log(err)
    done(null, data);
   })
};

Document is stored in database

When saving a document, MongoDB creates a field called "_id", which is a unqiue alphanumeric(letter + number) key. Searching records by _id is super common operation in MongoDB.

Finding records

  • find(condition) : find multiple records matched with the conditions
  • findOne(condition) : find the first record matched with the condition

Object ID

Once model instance is saved in the database, how do we know which one is which if the name is all the same? Finding a specific record is done with object id since each record in database has a different object id.

Deleting records

  • model(instance).remove
  • model(whole collections).remove
  • model.findOneAndRemove
    1. Create and save a new record
    1. Use findOneAndRemove to remove the record
    1. Use findOne to check if the removed record exists. It should be null if deleted.

Updating records

  • model(instance).update
  • model(whole collections).update
myModel.update({}, {$inc : { weight : 1 } }) // update whole collections, increasing weight property by 1 
  • model.findOneAndUpdate
    1. Create a save a new record
    1. Use findOneAndUpdate to update the record
    1. Use findOne to check the updated record. Its value should be changed.

Testing With Mocha

Mocha is a testing framework used to make test cases. Running tests consistently ensures newly added features are well integrated with previous ones.

You can test such as :

  • Creating records
  • Reading records
  • Updating records
  • Deleting records

Install Mocha like below

npm install mocha --save

// Installing mocha is not required for production setting.
npm install mocha --save-dev

Assert

Assert is a built-in module in Node.js. It evaluates a value parameter and if it is not true, throw error.

assert(value, message) // message is optional

Mocha configuration with Package.json

Configurate Mocha like below in Package.json to use Mocha with command npm test.

  "scripts": {
    "test": "node_modules/.bin/mocha $(find your/foler/directory -name '*.js') --recursive -w",
    "start": "nodemon"
  },

Handling Asynchronous Request With Mocha

Saving model into database is an asynchronous request. Deliver 'done' function parameter provided by Node.js and call it after the asynchronous request is done.

myModel.save()
       .then(function(done) {
           // do what is needed
           done(); // finish the asynchronous request
       }); 

When the done parameter is not properly delivered

When delivered

Login and Hash

Checking user info in collection(before password hashing

User password after hashing

User login failed with wrong password

Token

With json web token npm library, a token is created like below.

const token = jsonWebToken.sign(user._id.toHexString(), 'myToken')
  • Client : setting the token into cookie
  • Server : setting the token into database

Configuration

During connecting MongoDB using mongoose/express, database info such as username and password is required and can be seen in codes. Also, sensitive information such as API key should not be displayed in public neither. Thus, environment variable/file is needed to manage that.

// Environment variable in Node.js
// The process.env property returns an object containing the user environment.
process.env // global object. approachable in whole application. 

Comparison With Relational Database

Relational DB : SQL

Create two different tables and tangle them with SQL. 

MongoDB : No-SQL

Create two different objects and nest. 

const mongoose = require('mongoose')
const Schema = mongoose.Schema

const BookSchema = new Schema({
    title: String, 
    pages: Number
})

const AuthorScheam = new Schema({
    name: String,
    age: Number, 
    book: [BookSchema] // nested
}) 

// mongoose.model(model name, model schema)
const Author = mongoose.model('Author', AuthorSchema)
module.exports = Author
 
 
728x90

댓글


loading