melius
[MongoDB] Document Database 본문
MongoDB는 대표적인 NoSQL이며, Document Database로 분류된다.
1. RDB(Relational Database)와의 용어 차이
RDB | MongoDB |
Table | Collection |
Row | Document |
Column | Field |
Primary Key | Object_ID Field |
RDB는 Row 추가시 각 Column에 형식에 맞는 값만 들어 갈 수 있으나, MongoDB의 경우에는 정해진 형식이 따로 없고 Document마다 Field가 다를 수 있다. 또한 Collection간 JOIN기능이 없다.
2. 실행하기
https://docs.mongodb.com/manual/reference/configuration-options
mongodb를 실행할때 Configuration 파일이 있으면 실행시에 편리하다.
// db.conf
storage:
dbPath: "D:\\mongodb\\data"
net:
bindIp: 127.0.0.1
port: 27017
security:
authorization: disabled
사용자 계정에 비밀번호 설정후 authorization를 enabled로 변경하면, 비밀번호를 입력해야지 DB에 접근할 수 있다. MongoDB를 실행하는 명령은 아래와 같다.
$ mongod -f d:\mongodb\db.conf
3. Mongo Shell 설치 및 실행
https://docs.mongodb.com/manual/mongo
Mongo shell은 MongoDB에 직접적으로 명령을 입력할 수 있는 Interactive JavaScript Interface이다. MongoDB Server를 설치하면 Mongo shell는 자동으로 설치되며 아래와 같이 실행한다.
$ mongo --port 28015
$ mongo "mongodb://mongodb0.example.com:27017"
$ mongo -u root -p 0000 mongodb://192.168.0.2:27017
Mongo shell만 설치하려면 아래의 링크 참고
https://docs.mongodb.com/mongodb-shell
$ mongosh -u root -p 0000 mongodb://192.168.0.2:27017
4. Mongo Shell 명령어
Mongo shell 실행후 사용자 등록은 아래와 같다.
> use admin
> db.createUser({user:'root', pwd:'0000', roles:['root']});
> db.changeUserPassword('root', '1234'); // 암호변경
기본적인 shell 명령어는 아래와 같다.
// db
> show dbs // DB 리스트 보기
> use node // 사용 DB 변경
> db // 현재 사용 DB 확인
// collection
> show collections // collection 리스트 보기
> db.createCollection('users'); // collection 생성
> db.users.drop(); // collection 삭제
// create
db.users.insertOne({ name: 'jang', age: 43 });
// read
> db.users.find({});
// db.users.find({<field>: <value>, ... }, {<field>: <value>, ... });
> db.users.find({ name: 'jang' }, { age: true });
// update
db.users.update({ name: 'hero' }, { $set: { age: 31 } });
// delete
db.users.remove({ name: 'hero' });
5. MongoDB Driver for Node.js
https://www.npmjs.com/package/mongodb
https://docs.mongodb.com/drivers/node/current/quick-start
Node.js에서 MongoDB를 사용하기 위해서 MongoDB NodeJS Driver 패키지를 설치한다.
$ npm install mongodb
기본적인 CRUD는 아래와 같다.
const MongoClient = require('mongodb').MongoClient;
// Connection URL
// const url = 'mongodb://localhost:27017';
const url = 'mongodb://root:0000@192.168.0.57:27017';
// const url = 'mongodb://192.168.0.57:27017/mydb';
// const url = 'mongodb+srv://<user>:<password>@<cluster-url>?retryWrites=true&writeConcern=majority';
const dbName = 'mydb';
const client = new MongoClient(url);
// Use connect method to connect to the server
client.connect(function (error) {
if (error) console.log({ error });
else {
console.log('Connected successfully to server');
const db = client.db(dbName);
insertMany(db);
// find(db);
// updateOne(db);
// deleteOne(db);
client.close();
}
});
function insertMany(db) {
const collection = db.collection('mycollection');
collection.insertMany([{ a: 1 }, { a: 2 }, { a: 3 }], function (error, result) {
if (error) console.log({ error });
else console.log({ result });
});
}
function find(db) {
const collection = db.collection('mycollection');
collection.find({}).toArray(function (error, result) {
if (error) console.log({ error });
else console.log({ result });
});
}
function updateOne(db) {
const collection = db.collection('mycollection');
collection.updateOne({ a: 2 }, { $set: { b: 1 } }, function (error, result) {
if (error) console.log({ error });
else console.log({ result });
});
}
function deleteOne(db) {
const collection = db.collection('mycollection');
collection.deleteOne({ a: 3 }, function (error, result) {
if (error) console.log({ error });
else console.log({ result });
});
}
6. Mongoose
https://mongoosejs.com/docs/index.html
https://en.wikipedia.org/wiki/Mongoose
RDB를 편리하게 사용하기 위해서 Sequelize(https://sequelize.org)와 같은 ORM(Object Relational Mapping)이 있는 것과 유사하게, MoogoDB에는 ODM(Object Document Mapping)이라 불리는 Mongoose가 있다.
const Cat = mongoose.model('Cat', { name: String });
const kitty = new Cat({ name: 'Zildjian' });
kitty.save().then(() => console.log('meow'));
원래 MoogoDB에서 Document에 입력되는 Field에는 제한사항이 없지만, Mongoose는 Schema라는 개념을 이용해서 RDB의 Column 설정과 유사하게 Document의 각 Field에 제한사항을 설정할 수 있게 한다. 즉, Collection을 RDB의 Table과 유사하게 동작할 수 있도록 한다.
$ npm install mongoose
스키마 설정은 아래와 같다.
// schemas/user.js
const mongoose = require('mongoose');
const { Schema } = mongoose;
const userSchema = new Schema({
name: {
type: String,
required: true,
unique: true
},
age: {
type: Number,
required: true
}
});
module.exports = mongoose.model('User', userSchema);
RDB에서는 외래키(Foreign Key)가 있어서 다른 Table의 Row를 연결 할 수 있다. Mongoose에서도 다른 Collection의 Document를 참조할 수 있는 외래키(Foreign Key)와 유사한 기능을 지원한다. 참조 설정은 아래와 같다.
// schemas/reply.js
const mongoose = require('mongoose');
const { Schema } = mongoose;
const { Types } = Schema;
const commentSchema = new Schema({
replier: {
type: Types.ObjectId,
required: true,
ref: 'User'
},
reply: {
type: String,
required: true
}
});
module.exports = mongoose.model('Reply', replySchema);
기본적인 CRUD는 아래와 같다.
const mongoose = require('mongoose');
// load schemas
const User = require('./schemas/user');
const Reply = require('./schemas/reply');
// connect to mongodb
const { connection } = mongoose;
const url = 'mongodb://root:0000@192.168.0.3:27017';
connection.on('error', error => console.log('connection.error', { error }));
connection.on('disconnected', () => console.log('connection.disconnected'));
// mongoose.set('debug', true);
mongoose.connect(url, {
dbName: 'mydb',
useNewUrlParser: true,
useUnifiedTopology: true
}, error => console.log('connect', { error }));
async function createUser() {
const user = await User.create({
name: 'user' + parseInt(Math.random() * 100),
age: parseInt(Math.random() * 100)
});
console.log({ user });
connection.close();
}
async function findUser() {
const users = await User.find({});
// const users = await User.find({ name: 'user39' });
console.log({ users });
connection.close();
}
async function createReply() {
const user = await User.findOne({ name: 'user39' });
console.log({ user });
const reply = await Reply.create({
replier: user.id, // user._id
reply: 'hello user43'
});
console.log({ reply });
const result = await Reply.populate(reply, { path: 'replier' });
console.log({ result });
connection.close();
}
async function findReply() {
const user = await User.findOne({ name: 'user39' });
// const replys = await Reply.find({ replier: user.id });
const replys = await Reply.find({ replier: user.id }).populate('replier');
console.log(replys);
connection.close();
}
async function updateReply() {
const user = await User.findOne({ name: 'user39' });
const reply = await Reply.findOne({ replier: user.id });
console.log(reply);
const result = await Reply.updateOne({
// id: reply.id // not work
_id: reply.id
}, {
reply: 'bye ' + parseInt(Math.random() * 100)
});
console.log(result);
connection.close();
}
async function removeReply() {
const user = await User.findOne({ name: 'user39' });
const reply = await Reply.findOne({ replier: user.id });
console.log(reply);
const result = await Reply.remove({
// id: reply.id // not work
_id: reply.id
});
console.log(result);
connection.close();
}
createUser();
// findUser();
// createReply();
// findReply();
// updateReply();
// removeReply();
'et cetera' 카테고리의 다른 글
[Mac] 주요 명령어 (0) | 2020.11.22 |
---|---|
[Git] 명령어 (0) | 2020.10.25 |
[Chrome] 유용한 기능 (0) | 2020.09.01 |
[CMD] 파일검색 (0) | 2020.08.17 |
[VS Code] Django pylint(no-member) error (0) | 2020.07.10 |