In MongoDB, performing a join is slightly different compared to relational databases like MySQL or PostgreSQL. Since MongoDB is a NoSQL database, data is usually stored in collections rather than tables, and joins are achieved using the $lookup stage in an aggregation pipeline.
What Is a Join in MongoDB?
A join combines data from two or more collections based on a related field. In MongoDB:
- Collections Replace Tables: Joins happen between collections.
- $lookup Stage: Joins are implemented using the
$lookup
aggregation operator. - One-to-One or One-to-Many: Supports both relationships between collections.
Key Features of MongoDB Join
- Combines Collections: Fetch related data from multiple collections in a single query.
- Flexible Relationships: Supports complex relationships such as embedding or referencing.
- Efficient Aggregation: Joins are part of the MongoDB aggregation framework for powerful data manipulation.
Prerequisites
- MongoDB Installed: Download MongoDB from mongodb.com.
- Node.js Installed: Download and install Node.js from nodejs.org.
- MongoDB Shell or Compass Installed: Use either for database management.
Basic Syntax of $lookup
db.collectionName.aggregate([
{
$lookup: {
from: "otherCollection",
localField: "fieldInThisCollection",
foreignField: "fieldInOtherCollection",
as: "joinedField"
}
}
]);
- from: The collection to join with.
- localField: The field in the current collection.
- foreignField: The field in the other collection to match.
- as: The name of the field to store the joined results.
Example Dataset
users Collection:
[
{ "_id": 1, "name": "Alice", "cityId": 101 },
{ "_id": 2, "name": "Bob", "cityId": 102 },
{ "_id": 3, "name": "Charlie", "cityId": 103 }
]
cities Collection:
[
{ "_id": 101, "cityName": "New York" },
{ "_id": 102, "cityName": "London" },
{ "_id": 103, "cityName": "San Francisco" }
]
Method 1: Perform Join in MongoDB Shell
Step 1: Open MongoDB Shell
Run the following command:
mongosh
Step 2: Switch to a Database
Select your database:
use myDatabase
Step 3: Use $lookup to Join
Perform a join between users and cities:
db.users.aggregate([
{
$lookup: {
from: "cities",
localField: "cityId",
foreignField: "_id",
as: "cityDetails"
}
}
]);
Explanation:
- from: “cities”: Joins with the cities collection.
- localField: “cityId”: Matches the cityId field in
users
. - foreignField: “_id”: Matches the _id field in cities.
- as: “cityDetails”: Stores the joined data under the cityDetails field.
Method 2: Perform Join in Node.js
Step 1: Install MongoDB Driver
Run the following command:
npm install mongodb
Step 2: Perform Join Using Node.js
Create a file named app.js and write the following code:
const { MongoClient } = require('mongodb');
// Connection URL
const url = 'mongodb://localhost:27017';
const client = new MongoClient(url);
// Database Name
const dbName = 'myDatabase';
async function performJoin() {
try {
await client.connect();
console.log('Connected successfully to MongoDB');
const db = client.db(dbName);
const collection = db.collection('users');
// Perform the join
const result = await collection.aggregate([
{
$lookup: {
from: "cities",
localField: "cityId",
foreignField: "_id",
as: "cityDetails"
}
}
]).toArray();
console.log('Joined results:', result);
} catch (err) {
console.error('Error performing join:', err);
} finally {
await client.close();
}
}
performJoin();
Output:
[
{
"_id": 1,
"name": "Alice",
"cityId": 101,
"cityDetails": [
{ "_id": 101, "cityName": "New York" }
]
},
{
"_id": 2,
"name": "Bob",
"cityId": 102,
"cityDetails": [
{ "_id": 102, "cityName": "London" }
]
}
]
Method 3: Perform Join Using MongoDB Compass
Step 1: Open MongoDB Compass
- Launch Compass and connect to your MongoDB server (mongodb://localhost:27017).
- Select your database and collection.
Step 2: Use the Aggregation Tab
- Go to the Aggregation tab.
- Click “Add Stage” and select $lookup.
- Fill in the fields:
- From: cities
- Local Field: cityId
- Foreign Field: _id
- As: cityDetails
- Click “Run” to view the joined results.
Advanced Use of Joins
1. Unwind Results
Use $unwind to flatten the joined results:
db.users.aggregate([
{
$lookup: {
from: "cities",
localField: "cityId",
foreignField: "_id",
as: "cityDetails"
}
},
{ $unwind: "$cityDetails" }
]);
2. Filter Joined Data
Filter results after performing the join:
db.users.aggregate([
{
$lookup: {
from: "cities",
localField: "cityId",
foreignField: "_id",
as: "cityDetails"
}
},
{ $match: { "cityDetails.cityName": "New York" } }
]);
Real-World Use Case
Imagine an e-commerce application where orders and products are separate collections. You want to fetch order details along with the product information.
Example: Joining Orders with Products
const ordersWithProducts = await db.collection('orders').aggregate([
{
$lookup: {
from: "products",
localField: "productId",
foreignField: "_id",
as: "productDetails"
}
}
]).toArray();
console.log(ordersWithProducts);