쿼리 필터
Coddy Node.js 여정의 MongoDB 데이터베이스 섹션에 포함된 레슨. 29개 중 9번째.
클라이언트는 특정 책만 원하는 경우가 많으며, 데이터베이스가 책을 골라낼 수 있습니다.
find에 전달하는 객체는 필터입니다. 필터의 모든 필드가 일치하면 문서가 일치합니다. 일반 값은 같음을 의미합니다. 연산자는 $로 시작하는 키로, 대신 비교를 수행합니다. $gte는 크거나 같음을, $lte는 작거나 같음을 의미합니다. 같은 필드의 두 연산자는 하나의 객체를 공유합니다. { total: { $gte: 20, $lte: 50 } }는 합계가 20에서 50 사이인 항목을 유지합니다.
// 20 이상인 결제 완료 주문
await orders.find({ status: 'paid', total: { $gte: 20 } }).toArray();자료형도 중요합니다. { $gte: '20' }은 문자열을 비교하며, MongoDB는 문자열을 숫자 필드와 절대 일치시키지 않습니다. req.query의 모든 값은 문자열이므로, 필터에 넣기 전에 Number()를 사용해 숫자로 변환하세요.
챌린지
쉬움이 단계에서는 Finding by ObjectId에서 작업한 프로젝트 파일(여기에는 server.js도 포함)이 아니라, 책장 API 프로젝트의 준비된 사본을 엽니다. 이전 작업은 해당 수업에 그대로 남아 있습니다. server.js를 수정하기 전에 제공된 파일을 읽어 보세요. 이 사본에는 책을 삽입하는 코드와 ObjectId 조회 경로가 들어 있습니다.
클라이언트는 일부 책만 원합니다. 특정 작가의 책이나 특정 연도의 책처럼요. 데이터베이스에서 책을 선택하게 하세요.
server.js에서GET /books를 변경하세요. 쿼리 문자열로 필터 객체를 만들고, 이를find에 전달하세요. 이 경로는 계속해서 책의 JSON 배열을 응답으로 반환합니다.?author=Jane%20Austen은author가 정확히Jane Austen인 책만 반환합니다. (%20은 URL에서 공백을 나타내는 방식입니다.)?from=1960은year가 1960 이상인 책을 반환합니다.?to=1980은 1980 이하인 책을 반환합니다. 두 값을 모두 지정하면 책의 연도가 두 값 사이에 있어야 하며, 두 연도도 범위에 포함됩니다. 어느 한쪽 값만 지정해도 됩니다.- 쿼리 값은 항상 문자열로 전달되지만, 저장된 연도는 숫자입니다.
from과to를 필터에 넣기 전에 숫자로 변환하세요. 그렇지 않으면 아무것도 일치하지 않습니다. - 쿼리가 없으면 이전과 마찬가지로 모든 책을 반환합니다. 직접 해 보세요:
GET /books?from=1960&to=1980을 보내면 Dune (1965)과 Kindred (1979)가 반환됩니다.GET /books?from=1970을 보내면 Kindred만 반환됩니다.GET /books?to=1900을 보내면 Emma (1815)만 반환됩니다.GET /books?author=Jane%20Austen을 보내면 Emma만 반환됩니다.GET /books를 보내면 세 권 모두 반환됩니다.
직접 해보기
import express from 'express';
import { MongoClient, ObjectId } from 'mongodb';
const client = new MongoClient('mongodb://localhost:27017');
const db = client.db('shelf');
const books = db.collection('books');
await books.insertMany([
{ title: 'Dune', author: 'Frank Herbert', year: 1965, isbn: '9780441013593', genre: 'scifi' },
{ title: 'Kindred', author: 'Octavia E. Butler', year: 1979, isbn: '9780807083697', genre: 'scifi' },
{ title: 'Emma', author: 'Jane Austen', year: 1815, isbn: '9780141439587', genre: 'classic' },
]);
const app = express();
app.use(express.json());
// 모든 오류 응답은 { error: message } 형식입니다.
function sendError(res, status, message) {
res.status(status).json({ error: message });
}
app.get('/', (req, res) => {
res.send('Bookshelf API');
});
app.get('/books', async (req, res) => {
const list = await books.find().toArray();
res.json(list);
});
app.post('/books', async (req, res) => {
const book = req.body;
await books.insertOne(book);
res.status(201).json(book);
});
app.get('/books/:id', async (req, res) => {
if (!ObjectId.isValid(req.params.id)) {
return sendError(res, 400, 'Not a valid id');
}
const book = await books.findOne({ _id: new ObjectId(req.params.id) });
if (!book) {
return sendError(res, 404, 'No such book');
}
res.json(book);
});
app.listen(3000, () => {
console.log('Bookshelf is running on port 3000');
});
MongoDB 데이터베이스의 모든 레슨
직접 연습해 보세요: Express 플레이그라운드