新聞中心
MongoDB同庫(kù)聯(lián)表查詢實(shí)踐:實(shí)現(xiàn)方法與示例解析

MongoDB 是一款流行的 NoSQL 數(shù)據(jù)庫(kù),其文檔型存儲(chǔ)結(jié)構(gòu)為開發(fā)人員提供了極高的靈活性,在實(shí)際應(yīng)用中,我們經(jīng)常需要從多個(gè)集合(表)中查詢數(shù)據(jù),這就涉及到同庫(kù)聯(lián)表查詢,與關(guān)系型數(shù)據(jù)庫(kù)不同,MongoDB 不支持 SQL 中的 JOIN 操作,但我們可以通過(guò)其他方式實(shí)現(xiàn)類似的功能,本文將介紹 MongoDB 同庫(kù)聯(lián)表查詢的實(shí)現(xiàn)方法,并通過(guò)示例進(jìn)行詳細(xì)解析。
實(shí)現(xiàn)方法
MongoDB 同庫(kù)聯(lián)表查詢主要有以下幾種方法:
1、嵌入式文檔(Embedding)
嵌入式文檔是一種將相關(guān)數(shù)據(jù)存儲(chǔ)在同一文檔中的方法,這種方式在查詢時(shí)不需要進(jìn)行聯(lián)表操作,因?yàn)樗袛?shù)據(jù)都在一個(gè)文檔中,如果我們有一個(gè)訂單集合和一個(gè)用戶集合,可以將用戶信息嵌入到訂單文檔中。
優(yōu)點(diǎn):查詢速度快,不需要進(jìn)行聯(lián)表操作。
缺點(diǎn):數(shù)據(jù)冗余,不易維護(hù)。
2、引用式文檔(Referencing)
引用式文檔通過(guò)在文檔中存儲(chǔ)關(guān)聯(lián)文檔的 ID,來(lái)實(shí)現(xiàn)文檔之間的關(guān)聯(lián),這種方式在查詢時(shí)需要先查詢主文檔,然后根據(jù)關(guān)聯(lián) ID 查詢關(guān)聯(lián)文檔。
優(yōu)點(diǎn):數(shù)據(jù)結(jié)構(gòu)清晰,易于維護(hù)。
缺點(diǎn):查詢時(shí)需要進(jìn)行多次查詢,性能相對(duì)較差。
示例:
// 訂單集合
{
"_id": ObjectId("5f1e5c3a8f3e3e8e8c3a3a3a3"),
"userId": ObjectId("5f1e5c3a8f3e3e8e8c3a3a3a4"),
"orderItems": [
{
"productId": ObjectId("5f1e5c3a8f3e3e8e8c3a3a3a5"),
"quantity": 2
}
]
}
// 用戶集合
{
"_id": ObjectId("5f1e5c3a8f3e3e8e8c3a3a3a4"),
"username": "張三",
"email": "[email protected]"
}
// 商品集合
{
"_id": ObjectId("5f1e5c3a8f3e3e8e8c3a3a3a5"),
"name": "蘋果",
"price": 5.0
}
3、聚合查詢(Aggregation)
MongoDB 的聚合查詢功能非常強(qiáng)大,可以通過(guò)多個(gè)階段的聚合操作實(shí)現(xiàn)聯(lián)表查詢,聚合查詢通常使用 $lookup 階段來(lái)實(shí)現(xiàn)關(guān)聯(lián)查詢。
優(yōu)點(diǎn):查詢效率較高,可以處理復(fù)雜的查詢邏輯。
缺點(diǎn):聚合查詢語(yǔ)法相對(duì)復(fù)雜,學(xué)習(xí)成本較高。
示例解析
下面以一個(gè)簡(jiǎn)單的示例來(lái)說(shuō)明 MongoDB 同庫(kù)聯(lián)表查詢的方法。
需求:查詢訂單及其對(duì)應(yīng)的用戶和訂單詳情。
1、使用嵌入式文檔實(shí)現(xiàn):
// 查詢訂單集合,同時(shí)包含用戶信息和訂單詳情
db.orders.aggregate([
{
$lookup: {
from: "users",
localField: "userId",
foreignField: "_id",
as: "user"
}
},
{
$lookup: {
from: "products",
localField: "orderItems.productId",
foreignField: "_id",
as: "orderItems.product"
}
},
{
$unwind: "$orderItems"
},
{
$unwind: "$orderItems.product"
},
{
$project: {
_id: 0,
orderNumber: 1,
user: {
_id: 0,
username: 1,
email: 1
},
orderItems: {
_id: 0,
productId: 1,
quantity: 1,
product: {
_id: 0,
name: 1,
price: 1
}
}
}
}
]);
2、使用引用式文檔實(shí)現(xiàn):
// 查詢訂單集合,僅包含訂單基本信息和用戶 ID
const orders = db.orders.find().toArray();
// 遍歷訂單,查詢用戶信息和訂單詳情
const result = orders.map(order => {
const user = db.users.findOne({ _id: order.userId });
const orderItems = order.orderItems.map(item => {
const product = db.products.findOne({ _id: item.productId });
return {
...item,
product: {
_id: product._id,
name: product.name,
price: product.price
}
};
});
return {
...order,
user: {
_id: user._id,
username: user.username,
email: user.email
},
orderItems
};
});
console.log(result);
3、使用聚合查詢實(shí)現(xiàn):
db.orders.aggregate([
{
$lookup: {
from: "users",
localField: "userId",
foreignField: "_id",
as: "user"
}
},
{
$unwind: "$user"
},
{
$lookup: {
from: "products",
localField: "orderItems.productId",
foreignField: "_id",
as: "orderItems.product"
}
},
{
$unwind: "$orderItems"
},
{
$unwind: "$orderItems.product"
},
{
$project: {
_id: 0,
orderNumber: 1,
user: {
_id: 0,
username: 1,
email: 1
},
orderItems: {
_id: 0,
productId: 1,
quantity: 1,
product: {
_id: 0,
name: 1,
price: 1
}
}
}
},
{
$group: {
_id: "$orderNumber",
user: { $first: "$user" },
orderItems: { $push: "$orderItems" }
}
}
]);
以上示例分別使用了嵌入式文檔、引用式文檔和聚合查詢實(shí)現(xiàn)了同庫(kù)聯(lián)表查詢,在實(shí)際應(yīng)用中,可以根據(jù)業(yè)務(wù)需求和數(shù)據(jù)結(jié)構(gòu)選擇合適的方法。
網(wǎng)頁(yè)標(biāo)題:mongodb實(shí)現(xiàn)同庫(kù)聯(lián)表查詢方法示例
本文來(lái)源:http://m.fisionsoft.com.cn/article/dhhdich.html


咨詢
建站咨詢
