MongoDB๋ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ JOIN๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ $lookup ๋ฉ์๋๋ฅผ ํตํด ์ง์ํฉ๋๋ค. $lookup
์ ํ ์ปฌ๋ ์
์ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฅธ ์ปฌ๋ ์
๊ณผ ๊ฒฐํฉํ ๋ ์ฌ์ฉ๋๋ฉฐ, ์ด๋ฅผ ํตํด ์ฌ๋ฌ ์ปฌ๋ ์
๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์กฐํฉํ ์ ์์ต๋๋ค. ์ด๋ฒ ๊ธ์์๋ Node.js์ MongoDB๋ฅผ ์ฐ๋ํ์ฌ $lookup
๋ฉ์๋๋ฅผ ์ฌ์ฉํด ๋ฐ์ดํฐ๋ฅผ ์กฐ์ธํ๋ ๋ฐฉ๋ฒ์ ์ค๋ช
ํ๊ฒ ์ต๋๋ค.
MongoDB์ $lookup ๋ฉ์๋๋?
MongoDB์์ $lookup
์ ๋ ๊ฐ์ ์ปฌ๋ ์
์ ์กฐํฉํ์ฌ ํ๋์ ๊ฒฐ๊ณผ๋ฅผ ์์ฑํ๋ ๋ฉ์๋์
๋๋ค. ์ด๋ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ JOIN๊ณผ ์ ์ฌํ ์ญํ ์ ํ๋ฉฐ, ์ฃผ๋ก aggregate
ํ์ดํ๋ผ์ธ์์ ์ฌ์ฉ๋ฉ๋๋ค. $lookup
์ ๊ธฐ๋ณธ์ ์ผ๋ก ํ ์ปฌ๋ ์
์ ํ๋๋ฅผ ๋ค๋ฅธ ์ปฌ๋ ์
์ ํ๋์ ๋งค์นญํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๊ฒฐํฉํฉ๋๋ค.
$lookup ๊ธฐ๋ณธ ๊ตฌ์กฐ
MongoDB์ $lookup
๊ธฐ๋ณธ ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
{
$lookup: {
from: 'target_collection', // ์กฐ์ธํ ์ปฌ๋ ์
์ ์ด๋ฆ
localField: 'current_field', // ํ์ฌ ์ปฌ๋ ์
์์ ์ฐธ์กฐํ ํ๋
foreignField: 'target_field', // ๋ค๋ฅธ ์ปฌ๋ ์
์์ ์ผ์นํ ํ๋
as: 'result_field' // ๊ฒฐํฉ๋ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ ํ๋ ์ด๋ฆ
}
}
์ด ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ์ ๋ฐฉ์์ผ๋ก ์๋ํฉ๋๋ค:
- from: ๋ค๋ฅธ ์ปฌ๋ ์ ์ ์ด๋ฆ์ ์ง์ ํฉ๋๋ค.
- localField: ํ์ฌ ์ปฌ๋ ์ ์ ํ๋ ์ค ์กฐ์ธ์ ์ฌ์ฉํ ํ๋๋ฅผ ์ง์ ํฉ๋๋ค.
- foreignField: ๋ค๋ฅธ ์ปฌ๋ ์ ์์ ์ผ์น์ํฌ ํ๋๋ฅผ ์ง์ ํฉ๋๋ค.
- as: ์กฐ์ธ๋ ๊ฒฐ๊ณผ๊ฐ ์ ์ฅ๋ ์๋ก์ด ํ๋์ ์ด๋ฆ์ ์ง์ ํฉ๋๋ค.
Node.js์ MongoDB ์ฐ๋ํ๊ธฐ
MongoDB์์ $lookup์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์กฐํฉํ๋ ค๋ฉด ๋จผ์ Node.js์ MongoDB๋ฅผ ์ฐ๋ํด์ผ ํฉ๋๋ค. mongodb
ํจํค์ง๋ฅผ ์ฌ์ฉํ์ฌ ์ฐ๊ฒฐ์ ์ค์ ํ๋ ๋ฐฉ๋ฒ์ ์ค๋ช
ํ๊ฒ ์ต๋๋ค.
1. Node.js ํ๋ก์ ํธ ์ค์
MongoDB์ Node.js๋ฅผ ์ฐ๊ฒฐํ๊ธฐ ์ํด, ๋จผ์ Node.js ํ๋ก์ ํธ๋ฅผ ์ด๊ธฐํํ๊ณ ํ์ํ ํจํค์ง๋ฅผ ์ค์นํฉ๋๋ค.
$ mkdir myapp
$ cd myapp
$ npm init -y
$ npm install mongodb
2. MongoDB ์ฐ๊ฒฐ ์ค์
์ด์ MongoDB ์๋ฒ์ ์ฐ๊ฒฐํ๋ ๊ธฐ๋ณธ ์ฝ๋๋ฅผ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค. MongoClient
๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ MongoDB์ ์ฐ๊ฒฐํฉ๋๋ค.
// app.js
const { MongoClient } = require('mongodb');
// MongoDB ์ฐ๊ฒฐ URL
const url = 'mongodb://localhost:27017'; // ๋ก์ปฌ MongoDB URL
const client = new MongoClient(url);
// ์ฌ์ฉํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ด๋ฆ
const dbName = 'myDatabase';
async function main() {
try {
// MongoDB ์ฐ๊ฒฐ
await client.connect();
console.log('MongoDB์ ์ฑ๊ณต์ ์ผ๋ก ์ฐ๊ฒฐ๋์์ต๋๋ค.');
// ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ํ
const db = client.db(dbName);
console.log(`๋ฐ์ดํฐ๋ฒ ์ด์ค ${dbName} ์ ํ๋จ.`);
} catch (error) {
console.error('MongoDB ์ฐ๊ฒฐ ์ค ์ค๋ฅ ๋ฐ์:', error);
} finally {
// MongoDB ์ฐ๊ฒฐ ์ข
๋ฃ
await client.close();
console.log('MongoDB ์ฐ๊ฒฐ์ด ์ข
๋ฃ๋์์ต๋๋ค.');
}
}
main();
์ ์ฝ๋๋ MongoDB ์๋ฒ์ ์ฐ๊ฒฐํ๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ ํํ๋ ๊ธฐ๋ณธ ์ค์ ์ ๋๋ค. ์ด์ MongoDB์์ $lookup์ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์กฐํฉํ๋ ๋ฐฉ๋ฒ์ ์ดํด๋ณด๊ฒ ์ต๋๋ค.
MongoDB์์ ์ปฌ๋ ์ ์กฐ์ธํ๊ธฐ: $lookup ์ฌ์ฉ๋ฒ
MongoDB์์ $lookup์ ์ฌ์ฉํ์ฌ ๋ ๊ฐ ์ด์์ ์ปฌ๋ ์
์ ๊ฒฐํฉํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด๊ฒ ์ต๋๋ค. ์๋ฅผ ๋ค์ด, users
์ปฌ๋ ์
๊ณผ orders
์ปฌ๋ ์
์ ์กฐํฉํ์ฌ ๊ฐ ์ฌ์ฉ์์ ๊ทธ๋ค์ด ์ฃผ๋ฌธํ ์ํ ์ ๋ณด๋ฅผ ๊ฒฐํฉํ ์ ์์ต๋๋ค.
1. $lookup์ ์ฌ์ฉํ ๊ธฐ๋ณธ ์กฐ์ธ
๋ค์ ์ฝ๋๋ users
์ปฌ๋ ์
๊ณผ orders
์ปฌ๋ ์
์ ์กฐํฉํ์ฌ ์ฌ์ฉ์์ ๊ทธ๋ค์ ์ฃผ๋ฌธ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๋ ์์์
๋๋ค.
// users์ orders ์ปฌ๋ ์
์กฐ์ธ ์์
async function joinUsersAndOrders() {
try {
await client.connect();
console.log('MongoDB์ ์ฑ๊ณต์ ์ผ๋ก ์ฐ๊ฒฐ๋์์ต๋๋ค.');
const db = client.db(dbName);
const usersCollection = db.collection('users');
// users ์ปฌ๋ ์
๊ณผ orders ์ปฌ๋ ์
์ ์กฐํฉ
const results = await usersCollection.aggregate([
{
$lookup: {
from: 'orders', // ์กฐ์ธํ ์ปฌ๋ ์
์ด๋ฆ
localField: '_id', // users ์ปฌ๋ ์
์ ํ๋
foreignField: 'user_id', // orders ์ปฌ๋ ์
์์ ๋งค์นญํ ํ๋
as: 'user_orders' // ๊ฒฐ๊ณผ๊ฐ ์ ์ฅ๋ ํ๋
}
}
]).toArray();
console.log('์กฐ์ธ๋ ๊ฒฐ๊ณผ:', results);
} catch (error) {
console.error('๋ฐ์ดํฐ ์กฐ์ธ ์ค ์ค๋ฅ ๋ฐ์:', error);
} finally {
await client.close();
console.log('MongoDB ์ฐ๊ฒฐ์ด ์ข
๋ฃ๋์์ต๋๋ค.');
}
}
joinUsersAndOrders();
์ ์ฝ๋๋ users
์ปฌ๋ ์
์์ _id
ํ๋๋ฅผ ๊ธฐ์ค์ผ๋ก orders
์ปฌ๋ ์
์ user_id
ํ๋์ ์กฐํฉํ์ฌ ์ฌ์ฉ์์ ์ฃผ๋ฌธ ์ ๋ณด๋ฅผ ๊ฒฐํฉํ๋ ์์์
๋๋ค. ๊ฒฐ๊ณผ๋ user_orders
ํ๋์ ์ ์ฅ๋ฉ๋๋ค.
2. ์ฌ๋ฌ ์ปฌ๋ ์ ์กฐ์ธ
์ฌ๋ฌ ์ปฌ๋ ์
์ ๋์์ ์กฐ์ธํ์ฌ ๋ ๋ณต์กํ ์ฟผ๋ฆฌ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, products
์ปฌ๋ ์
๊น์ง ํจ๊ป ์กฐํฉํ์ฌ ๊ฐ ์ฌ์ฉ์๊ฐ ์ฃผ๋ฌธํ ์ ํ์ ์ธ๋ถ ์ ๋ณด๋ฅผ ํฌํจํ๋ ์์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
// users, orders, products ์ปฌ๋ ์
์ ์กฐ์ธํ๋ ์์
async function joinUsersOrdersAndProducts() {
try {
await client.connect();
console.log('MongoDB์ ์ฑ๊ณต์ ์ผ๋ก ์ฐ๊ฒฐ๋์์ต๋๋ค.');
const db = client.db(dbName);
const usersCollection = db.collection('users');
const results = await usersCollection.aggregate([
{
$lookup: {
from: 'orders', // ์ฒซ ๋ฒ์งธ ์กฐ์ธ
localField: '_id',
foreignField: 'user_id',
as: 'user_orders'
}
},
{
$lookup: {
from: 'products', // ๋ ๋ฒ์งธ ์กฐ์ธ
localField: 'user_orders.product_id',
foreignField: '_id',
as: 'order_products'
}
}
]).toArray();
console.log('์กฐ์ธ๋ ๊ฒฐ๊ณผ:', results);
} catch (error) {
console.error('๋ฐ์ดํฐ ์กฐ์ธ ์ค ์ค๋ฅ ๋ฐ์:', error);
} finally {
await client.close();
console.log('MongoDB ์ฐ๊ฒฐ์ด ์ข
๋ฃ๋์์ต๋๋ค.');
}
}
joinUsersOrdersAndProducts();
์ด ์ฝ๋๋ users
, orders
, products
์ธ ๊ฐ์ ์ปฌ๋ ์
์ ์กฐํฉํ๋ ์์์
๋๋ค. $lookup
์ ์ฌ๋ฌ ๋ฒ ์ฌ์ฉํ์ฌ ๊ฐ ์ฌ์ฉ์์ ์ฃผ๋ฌธ ์ ๋ณด์ ์ ํ ์ธ๋ถ ์ ๋ณด๋ฅผ ํจ๊ป ๊ฐ์ ธ์ต๋๋ค.
MongoDB ์ฐ๊ฒฐ ์ข ๋ฃ
๋ชจ๋ ๋ฐ์ดํฐ ์์
์ด ๋๋๋ฉด MongoDB ์ฐ๊ฒฐ์ ์์ ํ๊ฒ ์ข
๋ฃํด์ผ ํฉ๋๋ค. client.close()
๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์ฐ๊ฒฐ์ ์ข
๋ฃํ ์ ์์ต๋๋ค.
// MongoDB ์ฐ๊ฒฐ ์ข
๋ฃ
await client.close();
console.log('MongoDB ์ฐ๊ฒฐ์ด ์ข
๋ฃ๋์์ต๋๋ค.');
๊ฒฐ๋ก
์ด๋ฒ ๊ธ์์๋ Node.js์ MongoDB๋ฅผ ์ฌ์ฉํ์ฌ $lookup
๋ฉ์๋๋ก ์ปฌ๋ ์
์ ์กฐ์ธํ๋ ๋ฐฉ๋ฒ์ ์ดํด๋ณด์์ต๋๋ค. MongoDB์ $lookup
์ ์ฌ๋ฌ ์ปฌ๋ ์
์ ๋ฐ์ดํฐ๋ฅผ ๊ฒฐํฉํ์ฌ ๋ณต์กํ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ๋ ๋ฐ ๋งค์ฐ ์ ์ฉํฉ๋๋ค. ์ด ๊ฐ์ด๋๋ฅผ ํตํด MongoDB์์ ํจ์จ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์กฐํฉํ๊ณ ๋ค์ํ ์์ฉ ํ๋ก๊ทธ๋จ์ ๊ฐ๋ฐํ ์ ์์ต๋๋ค!
๋๊ธ ์ฐ๊ธฐ