티스토리 뷰

● 게시물마다 _id 번호를 다는 이유(PK가 있어야 하는 이유)
- MongoDB에 데이터를 저장할 때는 '_id'라는 값을 반드시 넣어야한다.(그래야 CRUD가 쉽다.)
- 만약 실수로 _id 값을 직접 넣어주지 않아도 MongoDB가 알아서 ObjectId()를 만들어서 _id 값을 강제로 넣어준다.
- ObjectId()로 만들어진 _id 값은 무작위 숫자&문자 조합인데 이게 싫으면 저장할 때 직접 _id 값을 넣어주면 된다.
- 현재 post 요청을 처리하는 코드는 아래와 같다.

※ _id = PK(Primary Key)라고 부르겠다.

app.post("/add", (req, res) => {
    db.collection('post').insertOne({title : req.body.title, date : req.body.date}, (error, result) => {
        console.log(req.body);
    });
    res.send("전송완료");
});

- 위의 코드에서 _id 값을 넣어주는 부분을 추가해보자  →  ( _id : 1)를 추가한다.

- 아래와 같이 작성하면 번호달아서 저장하기 끝이다.

app.post("/add", (req, res) => {
    db.collection('post').insertOne({_id : 1, title : req.body.title, date : req.body.date}, (error, result) => {
        console.log(req.body);
    });
    res.send("전송완료");
});

- 다만, 언제까지나 (_id : 1)과 같이 하드코딩을 사용할 수는 없다.
- 다른 종류의 DB는 PK 값을 자동으로 증가시켜주는 Auto Increment 같은 기능이 있는데 MongoDB는 Auto Increment 기능이 없다.
- Auto Increment 기능이 별로 필요없어서 그렇다. 정수말고 자동으로 부여되는 ObjectId만으로도 문제가 없기 때문이다.
- 어쨌든 Auto Increment 기능이 필요하면 이를 직접 만들어야 하는데 그러기 위해서는 지금까지 몇 개의 게시물이 발행됐는지를 기록해두어야 한다.(그러면 글이 발행될 때마다 유니크한 _id 값이 부여될 것이다.)
- 만약 기록이 가능하다면 위의 코드를 아래와 같이 변경할 수 있을 것이다.

app.post("/add", (req, res) => {
    db.collection('post').insertOne({_id : (지금까지 발행한 게시물 갯수 + 1), title : req.body.title, date : req.body.date}, (error, result) => {
        console.log(req.body);
    });
    res.send("전송완료");
});

● 게시물 갯수 기록을 위한 counter collection을 새로 만들고 데이터 넣기

- PK 값을 위해 지금까지 몇개의 게시물이 발행됐는지 기록해보자

- 이를 위해 mongodb atlas 홈페이지에 들어가서 collection을 하나 더 만들어보자

- 아래 사진 속 todoapp 데이터베이스에 있는 (+) 버튼을 누르면 collection(파일)을 하나 더 만들 수 있다.

- (+) 버튼을 누른 후 counter라는 이름의 collection을 생성해보자

- 새로 만든 counter collection에 데이터를 하나 집어 넣어 보자
- 우측에 있는 Insert Document 버튼을 누르면 강제로 항목을 하나 추가할 수 있다.

- 아래 사진과 동일하게 작성한 후 Insert 버튼을 누르자
* totalPost 라는 항목은 Int32로 셋팅해야한다.

- 이제 해당 collection 지금까지 몇 개의 게시물이 발행됐는지를 기록할 공간이다.
- 그 기록은 totalPost 라는 곳에 저장할 것이다.
- 현재는 아무 게시물도 발행되지 않았다고 가정하고 (초기값 = 0)으로 설정했다.


● findOne() function으로 counter collection 안의 totalPost 데이터를 꺼내보자

- counter collection을 이용해 POST 요청을 처리하는 코드를 수정해보자

app.post("/add", (req, res) => {
    db.collection('counter').findOne({name : 'totalPostCount'}, (error, result) => {
        // counter collection에서 총 게시물 갯수(totalPost)를 가져와서
        // totCount 변수에 저장
        let totCount = result.totalPost;
        console.log(result);
        console.log(`totCount : ${totCount}`);
        
        // 그 후에 INSERT 코드 실행
        db.collection('post').insertOne({_id : (totCount + 1), title : req.body.title, date : req.body.date}, (error, result) => {
            console.log(req.body);
            res.send("전송완료");
        });
    });
});

1. findOne function을 사용하면 collection 내에서 내가 원하는 '문서'를 쉽게 찾을 수 있다.
1-1. 찾은 결과는 callback function의 result 라는 이름의 변수에 담겨온다.(변수명은 마음대로)
2. result에서 totalPost 값을 추출해 totCount 변수에 저장
3. post collection에 insertOne function을 통해 PK값과 사용자 입력값을 함께 저장
4. res.send 코드를 이용해 응답(res.send 부분은 반드시 있어야한다.)

- 위의 코드를 하나하나씩 뜯어서 설명하면 아래와 같다.

// 누군가 /add 경로로 post 요청을 하면
app.post("/add", (req, res) => {
    // counter collection에서 "totalPostCount"로 저장해놓은 '문서'를 찾는다. 찾은 '문서'는 result라는 변수에 담겨온다.
    db.collection('counter').findOne({name : 'totalPostCount'}, (error, result) => {
        // result.totalPost로 총게시물 갯수를 뽑아 totCount 변수에 저장한 후 사용
        let totCount = result.totalPost;
        
        // post collection에 insertOne function을 통해 게시물 추가, 추가할 때 _id 값은 totCount 변수 이용
        db.collection('post').insertOne({_id : (totCount + 1), title : req.body.title, date : req.body.date}, (error, result) => {
            // res.send로 브라우저에게 글자를 보낸다.(res.render, res.redirect 등 이용 가능)
            res.send("전송완료");
        });
    });
});

● totalPost 값도 UPDATE 해줘야한다.

- 하나의 기능이 빠져있다.
- 글이 무사히 발행됐다면 counter collection 내의 totalPost 값도 (+1) 되어야한다.
- chatGPT 한테 물어봐서 아래와 같이 코드를 작성했다.

app.post("/add", (req, res) => {
    db.collection('counter').findOne({name : 'totalPostCount'}, (error, result) => {
        let totCount = result.totalPost;
        
        db.collection('post').insertOne({_id : (totCount + 1), title : req.body.title, date : req.body.date}, (error, result) => {
            res.send("전송완료");

            let updateDoc = {
                $set: {totalPost : (totCount + 1)}
            };

            db.collection('counter').updateOne({totalPost : totCount}, updateDoc);
        });
    });
})


● 개인적으로 테스트

db.collection('counter').findOne({name : 'totalPostCount'}, (error, result) => {

- 위의 코드에서 totalPost 값을 가져오려고 할 때 반드시 {name : 'totalPostCount'}라고 써야하는건 아닌것 같다.

- 현재 counter collection의 상태는 아래와 같다.(totalPost의 값은 위의 update 코드짜느라 증가됐다.)

 

- 위에서 findOne function을 사용하면 collection 내에서 내가 원하는 '문서'를 쉽게 찾을 수 있다고했다.

- 즉, counter collection에서 (_id, totalPost, name)이 들어있는 문서를 {name : 'totalPostCount'}를 이용해서 찾은것이다.

- 그렇다면 위의 사진을 기준으로 {_id : 6447a7c0f8d139d11447667c} 혹은 {totalPost : 2}를 이용해서도 Document를 가져와 원하는 값을 사용할 수 있는 것이다.

[{totalPost : 2}를 이용해 총게시물갯수 조회]

app.post("/add", (req, res) => {
    db.collection('counter').findOne({totalPost : 2}, (error, result) => {
        let totCount = result.totalPost;
        
        db.collection('post').insertOne({_id : (totCount + 1), title : req.body.title, date : req.body.date}, (error, result) => {
            res.send("전송완료");

            let updateDoc = {
                $set: {totalPost : (totCount + 1)}
            };

            db.collection('counter').updateOne({totalPost : totCount}, updateDoc);
        });
    });
})

- 아무런 문제없이 게시글을 작성했고 PK 값도 올바르게 SELECT, UPDATE 했다.

 

cf) MongoDB는 Key-value, Document 모델 저장 방식이다.

2023.04.21 - [Node.js+MongoDB] - #14 NoSQL DB 짧게 정리

 

#14 NoSQL DB 짧게 정리

- 웹 서비스 개발 시에 이용하는 DB는 대부분 (관계형 DB와 NoSQL DB) 중 하나로 분류된다. - 관계형 DB의 특징은 아래와 같다. 1. 거의 모든 곳에 사용할 수 있어 범용적 2. 구조화된 데이터의 CRUD에 좋

radderveloper.tistory.com

cf) ObjectId에 대한 글

https://koonsland.tistory.com/89

 

[MongoDB] 몽고DB의 ObjectID

MongoDB에서는 Collections에 데이터를 넣을때 ObejctID를 직접 넣어주지 않는 이상 자동으로 값이 부여가 되어 저장됩니다. 그리고 모든 데이터들은 각각의 ObjectID를 부여 받습니다. 이번 포스팅에서는

koonsland.tistory.com

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
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
글 보관함