프로젝션, 정렬 및 제한
Coddy Node.js 여정의 MongoDB 데이터베이스 섹션에 포함된 레슨. 29개 중 13번째.
‘최신 도서’ 목록에는 몇 권의 책에서 가져온 몇 가지 필드가 순서대로 필요합니다.
프로젝션은 쿼리가 반환할 필드를 선택합니다. 1은 필드를 포함하며, 0으로 설정하지 않는 한 _id도 함께 포함됩니다. 커서에서 sort({ field: -1 })은 높은 값에서 낮은 값 순으로 정렬합니다(1은 낮은 값에서 높은 값 순입니다). limit(n)은 처음 n개의 결과만 남깁니다.
// 가장 높은 점수 5개, name과 score만
await players
.find({}, { projection: { name: 1, score: 1, _id: 0 } })
.sort({ score: -1 })
.limit(5)
.toArray();두 호출을 어떤 순서로 연결하든 데이터베이스는 제한하기 전에 정렬합니다. limit 이후에 JavaScript에서 배열을 정렬하면 잘못된 다섯 개의 결과를 정렬하게 됩니다.
챌린지
쉬움이 단계에서는 Query Filters의 프로젝트 파일( server.js 포함)이 아니라, 과정에서 준비한 bookshelf API 프로젝트를 엽니다. 이전 작업은 해당 레슨에 그대로 남아 있습니다. server.js를 수정하기 전에 제공된 파일을 읽어 보세요. 이 사본에는 bookshelf 경로와 연도 범위 필터가 들어 있습니다.
홈 페이지에는 가장 최신 책이 표시되며, 제목과 연도만 나옵니다.
server.js에GET /books/newest경로를 추가하세요.GET /books/:id보다 위에 배치하세요. Express는 경로를 순서대로 확인하며,/books/:id도/books/newest와 일치합니다. 그러면newest를 ID로 취급해 400으로 응답하게 됩니다.- 이 경로는 책을
year기준으로 내림차순 정렬해 반환합니다. ?n=은 반환할 책의 수를 지정합니다.n이 없으면 3권을 반환합니다.- 각 책에는
title과year만 있고,_id나 다른 필드는 없습니다. 쿼리에서 필드를 선택하고, 책을 정렬한 다음 목록을 자르세요. 시작 코드에 있는 책의 경우,GET /books/newest?n=2는 다음을 반환합니다:직접 해보기:[ { "title": "Kindred", "year": 1979 }, { "title": "Dune", "year": 1965 } ]GET /books/newest를 전송하세요. Kindred (1979), Dune (1965), Emma (1815)가 이 순서로 표시되며, 각 책에는 제목과 연도만 나옵니다.GET /books/newest?n=1을 전송하면[ { "title": "Kindred", "year": 1979 } ]가 표시됩니다. 400 오류가 발생하면GET /books/:id가 요청을 처리한 것이므로, 새 경로를 그 위로 옮기세요.
직접 해보기
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 filter = {};
if (req.query.author) {
filter.author = req.query.author;
}
if (req.query.from || req.query.to) {
filter.year = {};
if (req.query.from) {
filter.year.$gte = Number(req.query.from);
}
if (req.query.to) {
filter.year.$lte = Number(req.query.to);
}
}
const list = await books.find(filter).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 플레이그라운드