Node.js Express MongoDB. 연결문을 연속해서 사용할 때 (+ 조건이 없을 때 전수검색법)

tennfin1·2023년 7월 31일
0

backend

목록 보기
4/18

코딩하다가 적고 싶어서 간단하게 적습니다

상황 : mongoDB에 저장된 데이터를 페이지네이션을 통해 불러올 것인데, 페이지네이션으로 특정페이지의 전체 데이터를 불러옴과 동시에, 데이터 개수를 가져오는 방법. + 조건 추가하기까지

1. 그냥 query를 2번 쓰는 방법

let conn = null
conn  = await client.connect(db_setting)

data = await conn.db("db_name")
	.collection("collection_name")
	.find({"id":id})
	.toArray()
	.skip((pagenum-1)*dataPerPage)
	.limit(dataPerPage)
	.sort({ time:1 })
	.toArray()
    
count = await conn.db("healthpartner")
    .collection("log")
    .countDocuments({"id":id});

설명 : data 할당에서 find (조건)을 통해서 데이터를 페이지네이션해서 가져옴
count 할당에서 countDocuments(조건)을 통해서 조건에 해당하는 전체 개수를 가져옴

장점 : 직관적으로 사용하기 쉬움
단점 : 그 외 모든 것

2. aggregate를 활용하는 법

const pipeline = [
            { $match: {"id":id} }, 
            { $sort: { time: 1 } },
            { $limit: dataPerPage }, 
            { $skip: (pagenum-1)*dataPerPage },
            { $group: { _id: null, totalCount: { $sum: 1 }, data: { $push: '$$ROOT' } } },
            { $project: { _id: 0, totalCount: 1, data: 1 } },
            ];
            
const result = await conn.db('db_name').collection("collection_name")
        .aggregate(pipeline)
        .toArray();

설명 : mongoDB 자체적으로 탑재되어 있는 기능입니다.
이는 FIND 명령으로는 처리할 수 없는 복잡한 데이터 분석 기능들을 제공합니다.
ex) SQL에서 GROUP BY 절로 처리할 수 있는 기능

장점 : query의 자체적인 기능이라 한번의 query 연결로 처리 가능

3. 트랜잭션(startSession) 이용

읽어보기 전 트랜잭션을 모르면 사용하는 이유를 검색해보기

//GPT를 이용한 예시 코드임

  	const session = client.startSession();
    
    // MongoDB 연결
    await client.connect();
    const database = client.db('yourDatabaseName');
    const collection1 = database.collection('collectionName1');
    const collection2 = database.collection('collectionName2');

    // 트랜잭션 시작
    session.startTransaction();

    // 트랜잭션 수행할 작업
    const operation1 = collection1.updateOne(
      { _id: 'documentId1' },
      { $set: { field1: 'value1' } },
      { session }
    );

    const operation2 = collection2.deleteOne(
      { _id: 'documentId2' },
      { session }
    );

    // 트랜잭션 작업 실행
    await Promise.all([operation1, operation2]);

    // 트랜잭션 커밋
    await session.commitTransaction();
    console.log('Transaction committed successfully');

설명: 안써봤음. 근데 2번 방식처럼 하나의 연결문으로 처리가 불가능하면 사용할 방법임

장점: Node.js로 다중 유저가 사용하는 것을 감안하면, 2개이상의 query(여기선 연결문)를 연달아 사용하면 race condition을 일으킬 수 있음.
2번의 방식으로 한번에 묶어서 실행하면 상관 없으나, 필연적으로 2개의 연결문을 사용해야만 하는 상황에서 유용할 것

추가 TIP

나중에 node-mongoDB 기초에 대한 글을 작성하면서 언급하겠지만,
front-end에서 빈 조건이 왔을 때 모든 데이터를 보내주는 방법은
1번의 경우에서는 find()안의 json 형태의 데이터 대신 undefined된 변수를 넣어주면 되고,
2번의 경우에서는 빈 json = {} 형태의 데이터를 넣어주면 됩니다.

작성한 모든 것은 틀릴 수 있습니다. 피드백 주시면 감사하겠습니다.

profile
심도깊은개발

1개의 댓글

comment-user-thumbnail
2023년 7월 31일

많은 도움이 되었습니다, 감사합니다.

답글 달기

관련 채용 정보