티스토리 뷰

web : back-end/node js

[node js] Express: MongoDB 데이터베이스 연동

무니웜테일패드풋프롱스 2020. 7. 5. 13:03

MongoDB 커넥션 풀

  1. mongoConnection으로 dbname에 해당하는 데이터베이스(클러스터)로 연결한다. 존재하지 않으면 생성해준다.
  2. 연결된 결과를 _db 변수에다 담아준다.
  3. getDb 메서드를 이용해 _db 변수를 반환한다.
const mongodb = require('mongodb');
const MongoClient = mongodb.MongoClient;
let _db;
const mongoConnect = (callback) =>{ // for connecting, and storing database 
    MongoClient.connect('mongodb+srv://moonhee:<password>.mongodb.net/shop?retryWrites=true&w=majority')
    .then(client =>{
        console.log('Connected');
        _db = client.db(); // <dbname> 으로 연결, 존재하지 않으면 table 생성 
        callback();
    })
    .catch(err=>{
        console.log(err)
        throw err;
    });
};

const getDb = () =>{ // mongoConnect에서 연결된 db로 access할 수 있도록 
    if(_db) return _db;
    throw 'No database found!';
}
exports.mongoConnect = mongoConnect;
exports.getDb = getDb;

 

MongoDB - 컬렉션 생성하기

  1. getDb를 import해서 생성된 클러스터를 가져온다.
  2. 컬렉션을 생성하고 수정 및 삭제하는 Model파일 내에서 Product 클래스를 만들어서 인스턴스 생성자와 save() 메서드를 만든다. 여기서 인스턴스 생성자는 인자값으로 이루어진 새로운 데이터를 만들어주고 save()메서드는 해당 데이터를 저장해준다. 
  3. save에서 만약, 해당 컬렉션이 없으면 새로 생성해준다.
  4. 그리고 해당 클래스를 exports해주고 컨트롤러에서는 exports된 Product클래스를 이용하면 된다.
const getDb = require('../util/database').getDb;
class Product{ 
    constructor(title, price, description, imageUrl){ // 컬렉션에 들어갈 인스턴스 생성자 
        this.title=title;
        this.price=price;
        this.description=description;
        this.imageUrl=imageUrl;
    }
    save(){  // 컬렉션 저장 및 생성 
        const db = getDb();
        // insert로 넘겨준 인자는 javascript에서 json으로 mongodb가 바꿔준다.
        db.collection('products')
       .insertOne(this)
        .then(result=>{
            console.log(result);
        })
        .catch(err=>console.log); 
        // mongoDb에게 데이터를 삽입할 table을 알려주는 메서드
        // 아직 table이 없으면 바로 create해준다.
        
    }
  
}

module.exports = Product;

 

컬렉션 내 저장된 데이터 반환하기

find() 메서드를 사용하는데 주의할점은 find()는 promise가 아니라 cursor를 반환하므로 toArray()를 통해 자바스크립트 형식으로 변환하여 return 해야한다.

    static fetchAll(){
        // find()자체는 promise가 아니라 cursor를 반환하므로 toArray를 해주어야한디
        const db = getDb();
        return db.collection('products')
        .find()
        .toArray() // 변환 
        .then(products=>{
            console.log(products);
            return products;
        })
        .catch(err=> {console.log(err)});
    }

 

특정 Id값을 가진 데이터를 반환하기

여기서 주의할점이 있다.

  1. 몽고db에서 id는 자동으로 _id 로 저장된다는 것이다. 'id'로 접근해서는 안된다.
  2. 몽고 db에서 id는 자동으로 ObjectId 타입으로 저장하기 때문에, 몽고 db 내_ id 값과 string을 비교할 수 없다.     따라서 스트링 형태의 id를 몽고 db내 _id와 비교하기위해서는mongodb 라이브러리를 import해서는                   new mongodb.ObjectId( id스트링) ; 로 인스턴스를 생성하여 비교하도록 한다.
   const mongodb = require('mongodb');
   static findById(ProductId){
        const db= getDb();
        return db.collection('products')
        .find({_id:new mongodb.ObjectId(ProductId)})
        .next() // find는 id에 해당하는 여러 cursor를 반환하므로 next를 호출하여 
               // 다음 document를 반환해준다. 
        .then(product=>{
            console.log(product);
            return product;
        })
        .catch(err=>{
            console.log(err);
        });
    }

 

그리고 컨트롤러에서 라우팅은 아래와 같이 구현하면 된다.

const Product = require('../models/product'); // Product Model Import 

exports.postAddProduct=(req,res,next)=>{ //상품 추가후 list 
    const title=req.body.title;
    const imageUrl=req.body.imageUrl;
    const price=req.body.price;
    const description=req.body.description;
    const product = new Product(title,price,description,imageUrl); //인스턴스 생성
    product.save().then(result => { //인스턴스 저장 
        console.log(result);
        res.redirect('/');
    })
    .catch(err => console.log(err));
};

exports.getProducts=(req,res,next)=>{
    Product.fetchAll()
    .then(products => {
        res.render('shop/product-list',{ 
            pageTitle:'ALL PRODUCTS',
            prods:products,
            path:'/products'
        });
    })
    .catch( err => {console.log(err)});
};

exports.getProduct=(req,res,next)=>{
    const prodId = req.params.productId;
    Product.findById(prodId)
    .then( (products)=>{
        res.render('shop/product-detail', {
            product: products,
            path:'/products',
            pageTitle:products.title
        });
    })
    .catch(err =>
        console.log(err));
}

 

참조:docs.mongodb.com/manual/reference/method/cursor.next/

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함