MongoDB는 NoSQL을 사용하는 database이다.
Node.Js Driver을 위한 MongoDB에 대한 정보:
https://www.mongodb.com/docs/drivers/node/current/
MongoDB Atlas에서 Cluster을 생성한다.
MongoDB driver를 설치해 연결 준비를 한다.
npm install --save mongodb
util/database.js
const mongodb = require('mongodb');
const MongoClient = mongodb.MongoClient;
const mongoConnect = (callback) => {
MongoClient.connect(
'connection string, replace password with your own pw.'
)
.then(result => {
console.log('connected!')
callback(result);
})
.catch(err => console.log(err));
}
module.exports = mongoConnect;
mongoConnect를 app.js에서 import하여 사용한다.
/app.js
const mongoConnect = require('./util/database');
mongoConnect(client => {
console.log(client);
app.listen(3000);
})
하지만 client를 edit 할때마다 계속하여 connection을 만들 수는 없기 때문에 client data를 export 할 수 있다.
let _db;
const mongoConnect = (callback) => {
MongoClient.connect(
'connection string, replace password with your own pw.'
)
.then(client => {
console.log('connected!')
_db = client.db("name_of_the_db");
callback();
})
.catch(err => {
throw err;
});
}
const getDb = () => {
if (_db) {
return _db;
}
throw "No Database found!";
}
exports.mongoConnect = mongoConnect;
exports.getDb = getDb;
Collection과 Document는 각각 SQL에서 Schema와 Record이다.
Product Collection을 만들고 Document를 생성하는 과정을 Object를 만드는 것을 통하여 할 수 있다.
class Product {
constructor(title, price, description, imageUrl, id) {
...
this._id = id ? new mongodb.ObjectId(id) : null;
}
getDb()의 값을 db라는 변수에 저장했을때 db.collection('name')은 collection을 생성한다.
db.collection('name').insertOne(Object)는 name collection에 document를 생성한다.
https://www.mongodb.com/docs/manual/reference/method/db.collection.insertOne/
db.collection('name').updateOne({filter})는 이미 존재하는 document를 업데이트 한다.
https://www.mongodb.com/docs/manual/reference/method/db.collection.updateOne/
this._id 에서 ternary statement를 사용하는 이유는 새로운 ObjectId를 만들면 save()에서 _id의 존재 유무에 따라 product가 새로 만들어 지는건지 update하는 건지 확인하는 if(this._id)가 항상 true이기 때문이다. 고로 새로운 product가 만들어 지지 않는다.
이를 통하여 save()를 만들 수 있다.
save() {
const db = getDb();
let dbOp;
if(this._id) {
//id, 즉 document가 이미 존재할때 업데이트 한다.
dbOp = db
.collection('products')
.updateOne({_id: this._id}, {$set: this});
}
else {
//document가 존재하지 않을때 새로 생성한다. 여기서 this에는 this_id의 값이 없다.
//id값이 없으므로 ObjectId()로 생성이 된다.
dbOp = db
.collection('products')
.insertOne(this);
}
return dbOp
.then(result => {
console.log(result);
})
.catch(err => {
console.log(err);
})
}
Product를 만들때 this_id = new mongodb.ObjectId(id)가 필요한 이유는 document가 저장될때 id값이 특별히 지정되지 않으면 default로 mongodb.ObjectId()로 저장되기 때문이다.
https://www.mongodb.com/docs/manual/reference/method/ObjectId/
$set은 field update operator 이다.
https://www.mongodb.com/docs/manual/reference/operator/update/set/
find() 와 필터를 사용한다. find()는 cursor을 반환하기에 next()나 toArray()를 사용해야 한다.
findOne()을 사용하면 element를 바로 반환하기에 하나만 찾는것이라면 더 편하다.
/models/product.js
static fetchAll() {
const db = getDb();
return db.collection('products')
.find()
.toArray()
.then(products => {
return products;
})
.catch(err => console.log(err));
}
static findById(prodId) {
const db = getDb();
return db.collection('products')
.find({_id: new mongodb.ObjectId(prodId)})
.next()
.then(product => {
console.log("these are the products ", product);
return product;
})
.catch(err => console.log(err));
}
https://www.mongodb.com/docs/mongodb-shell/crud/read/
deleteOne() 과 필터를 사용한다.
/models/product.js
static deleteById(prodId) {
const db = getDb();
return db.collection('products')
.deleteOne({_id: mongodb.ObjectId(prodId)})
.then(result => {
console.log('Deleted in product.js');
})
.catch(err => console.log(err));
}