그저 내가 되었고
🎯Node.js + mongoDB:: 중첩 조건으로 게시글 필터링하기 본문
1. 하고자 한 것: 위처럼 내가 찾고자 하는 조건(위치, 날짜, 시간, 인원)을 한꺼번에 받아서 게시글 필터링
2. 유의미한 구글링 키워드: mongodb overlap find, mongodb document query overlap find
3. 사용한 방법:
쿼리:: 쿼리로 find() 함수 이용하기; find() 함수 기본형에 쿼리를 추가해서 이용하면 다양한 조건으로 검색이 가능함.
<비교 쿼리>
쿼리 | 설명 |
$eq | equals, 일치하는 값을 찾는다. |
$gt | greater than, 지정된 값보다 큰 값을 찾는다. |
$gte | greater than or equals, 크거나 같은 값을 찾는다. |
$lt | less than, 지정된 값보다 작은 값을 찾는다. |
$lte | less than or equals, 작거나 같은 값을 찾는다. |
$ne | not equal, 일치하지 않는 모든 값을 찾는다.($eq의 부정) |
$in | 배열에 지정된 값 중 하나와 일치한 값을 찾는다. |
$nin | 배열에 지정된 값과 일치하지 않는 값을 찾는다. |
<논리 쿼리>
조건과 쿼리에 따른 결과를 반환하며, 조건은 2개 이상이 올 수 있음.
쿼리 | 설명 |
$or | 조건들 중 하나라도 true면 반환 (true: 조건과 일치, false: 조건과 불일치) |
$and | 조건들이 모두 true일 때 반환 |
$not | 조건이 false일 때 반환 |
$nor | 조건들이 모두 false일 때 반환 |
lodash 라이브러리:: for 중복 제거(혹시.. 혹시 모를 중복 제거하기 위해)
1) npm i --save lodash
2) controllers/posts 윗부분에 삽입
const _ = require('lodash');
3) 코드에서 사용할 때는 이런 식
let posts = [...filter]
posts = _.uniqBy(posts, "_id"); //중복 제거(Library Lodash)
4. 코드
posts.router.js
router.post("/filterPosts", postsController.filterPosts); //게시글 필터링
req.body //프런트에서 사용하는 라이브러리가 시간&날짜를 한꺼번에 입력받는 애라고 함. 그래서 원래는 date, time 따로 받도록 만들었다가 time 하나만 받는 걸로 코드 수정.
controllers/posts.js
const Posts = require("../schema/posts");
const _ = require('lodash');
//게시글 필터링
filterPosts = async (req, res, next) => {
try {
const {map, time, partyMember} = req.body;
const filterPosts = await this.postsService.filterPosts(map, time, partyMember);
res.status(200).json({data: filterPosts, message: "게시글 필터링 완료"});
} catch (e) {
res.status(e.status || 400).json({statusCode: e.status, message: e.message });
}
}
services/posts.js
//게시글 필터링
filterPosts = async(map, time, partyMember) => {
const filteredPostsData = await this.postsRepository.filterPosts(map, time, partyMember);
for (let i = 0 ; i < filteredPostsData.length; i++) {
const membersStatus = (filteredPostsData[i].confirmMember.length / filteredPostsData[i].partyMember);
if (membersStatus > 0 && membersStatus <= 0.3) {
filteredPostsData[i]["memberStatus"] = 0;
}
else if (membersStatus > 0.3 && membersStatus <= 0.6) {
filteredPostsData[i]["memberStatus"] = 1;
}
else if (membersStatus > 0.6 && membersStatus <= 0.9) {
filteredPostsData[i]["memberStatus"] = 2;
} else {
filteredPostsData[i]["memberStatus"] = 3;
}
}
return filteredPostsData
}
repositories/posts.js
//게시글 필터링
filterPosts = async (map, time, partyMember) => {
const filter = await Posts.find(
{
$and: [
{map: {$regex: new RegExp(`${map}`, "i")}},
{time: {$gte: time[0], $lte: time[1]}},
{partyMember: {$gte: partyMember[0], $lte: partyMember[1]}}
]
});
for (let i = 0; i < filter.length; i++) {
const findUser = await Users.findOne({userId: filter[i].userId})
filter[i]['userAvatar'] = findUser.userAvatar;
}
return filter;
}
5. 더 생각해볼 점:
✓get method에서 req.body 사용 가? 불가?:
처음에는 get으로 코드를 짰다가 swagger에서 오류 봉착(typeerror: failed to execute 'fetch' on 'window': request with get/head method cannot have body.)하여 post로 method를 변경했다.
postman에서는 아무 문제 없이 돌아갔었는데 swagger에서는 안되는걸 보니 특정 클라이언트에서는 get body가 무시되는 경우가 있는 것 같다.
✓req.body가 아닌 req.params로 구현하기: 네이버 쇼핑 상세 필터링, 11번가 쇼핑 상세 필터링 등은 전부 params를 쓴다고 함
↳참고; https://velog.io/@joonsikyang/React-Project-URL-parameters-Query-parameters
'개발 > DB' 카테고리의 다른 글
🌱mongoDB:: 배열 수정 관련 & JS::객체/배열 관련 (0) | 2022.12.01 |
---|---|
🌱mongoDB:: Array로 find? (0) | 2022.11.30 |
🌱mongoDB:: population (0) | 2022.11.29 |
🌱mongoDB:: relation 설정하기(populate 이용) (0) | 2022.11.26 |
🎯Node.js + mongoDB:: 게시판 검색 기능 (0) | 2022.11.22 |