Back/Node.js

Node.js Mongodb aggregate lookup

router.get('/answers/like', authMiddleware, async (req, res) => {
	try {
		const user = res.locals.user;
		let { page } = req.query;
		page = (page - 1 || 0) < 0 ? 0 : page - 1 || 0;

		const answerCount = await AnswerCard.find({ userId: user.userId });
		const myAnswerInfo = await AnswerCard.aggregate([
			{ $match: { userId: { $eq: user.userId } } },
			{
				$project: {
					_id: { $toString: '$_id' },
					questionId: 1,
					contents: 1,
					YYMMDD: 1,
					userId: 1,
					createdAt: 1
				}
			},
			{
				$lookup: { from: 'likes', localField: '_id', foreignField: 'answerId', as: 'likes' }
			},
			{
				$project: {
					questionId: 1,
					_id: 1,
					contents: 1,
					YYMMDD: 1,
					userId: 1,
					likes: { $size: '$likes' },
					createdAt: 1
				}
			},
			{ $sort: { likes: -1 } },
			{ $skip: page * 15 },
			{ $limit: 15 }
		]);

		const allMyAnswer = await Promise.all(
			myAnswerInfo.map(async (myAnswer) => {
				//좋아요 상태확인
				let currentLike = false;
				let checkCurrentLike = await Like.findOne({
					userId: user.userId,
					answerId: myAnswer['_id']
				});
				if (checkCurrentLike) {
					currentLike = true;
				}
				const questionInfo = await QuestionCard.findOne({
					_id: myAnswer['questionId']
				});
				const [questionCreatedUserInfo, like, comment] = await Promise.all([
					User.findOne({ id: questionInfo.userId }),
					Like.find({ answerId: myAnswer['_id'] }),
					CommentBoard.find({ cardId: myAnswer['_id'] })
				]);
				return {
					questionCreatedUserNickname: sanitize(questionCreatedUserInfo.nickname),
					questionCreatedUserId: questionCreatedUserInfo._id,
					questiontopic: questionInfo.topic,
					questionContents: sanitize(questionInfo.contents),
					answerContents: sanitize(myAnswer['contents']),
					answerCreatedAt: myAnswer['YYMMDD'],
					likeCount: like.length,
					commentCount: comment.length,
					currentLike: currentLike
				};
			})
		);
		return res.send({ answerCount: answerCount.length, allMyAnswer });
	} catch (err) {
		console.log(err);
		return res.status(400).json({ msg: 'fail' });
	}
});

좋아요 db와 게시글 db가 달라서 좋아요 순위로 내려줄 땐

 

look up을 통해서 db를 연결한 후 내려줬다.

 

match는 조건을 찾는 것이고,

 

lookup은 어떤 db를 참조할 것인지,

 

project는 무엇을 내려줄 것인지,

 

skip, limit은 무한스크롤을 사용할 때,

 

그렇게 해서 구한 값들을 for문을 통해 하나하나 배열에 push해줘서 배열을 만든 후

 

클라에 내려줬다.