本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
$lookup
Amazon DocumentDB $lookup 中的彙總階段可讓您在兩個集合之間執行左側外部聯結。此操作可讓您根據相符的欄位值,合併來自多個集合的資料。當您需要將相關集合的資料納入查詢結果時,此功能特別有用。
參數
-
from:要執行聯結的集合名稱。 -
localField:輸入文件中要與 相符的欄位foreignField。 -
foreignField:集合中from要比對之文件的欄位localField。 -
as:要新增至輸出文件的新欄位名稱,其中包含來自from集合的相符文件。 -
pipeline:如果指定localField和foreignField,則為選用。要在from集合上執行的彙總管道。管道會從from集合傳回文件。若要傳回所有文件,請指定空管道[]。管道不能包含$out或$merge階段。請參閱 聯結條件和相關子查詢 (MongoDB Shell)。 -
let:選用。定義要在pipeline階段中使用的變數的文件。使用變數表達式,從加入 的輸入文件中存取欄位pipeline。若要在管道階段中參考變數,請使用"$$<variable>"語法。請參閱 聯結條件和相關子查詢 (MongoDB Shell)。
範例 (MongoDB Shell)
下列範例示範將資料從orders集合加入customers集合的簡單$lookup操作。
建立範例文件
db.customers.insertMany([ { _id: 1, name: "Alice" }, { _id: 2, name: "Bob" }, { _id: 3, name: "Charlie" } ]); db.orders.insertMany([ { _id: 1, customer_id: 1, total: 50 }, { _id: 2, customer_id: 1, total: 100 }, { _id: 3, customer_id: 2, total: 75 } ]);
查詢範例
db.customers.aggregate([ { $lookup: { from: "orders", localField: "_id", foreignField: "customer_id", as: "orders" } } ]);
輸出
[
{
_id: 1,
name: 'Alice',
orders: [
{ _id: 2, customer_id: 1, total: 100 },
{ _id: 1, customer_id: 1, total: 50 }
]
},
{ _id: 3, name: 'Charlie', orders: [] },
{
_id: 2,
name: 'Bob',
orders: [ { _id: 3, customer_id: 2, total: 75 } ]
}
]
聯結條件和相關子查詢 (MongoDB Shell)
8.0.2 版的新功能。
除了單一等式比對之外,Amazon DocumentDB $lookup中的 也可以在聯結的集合上執行彙總管道。這支援不相關的子查詢,其會針對每個輸入文件執行相同的子查詢,並使用每個輸入文件欄位中定義的變數傳回與該文件相關的結果。
語法
若要執行關聯的子查詢,請使用 從輸入文件的欄位定義變數let,並在pipeline階段中參考變數:
{ $lookup: { from: <collection to join>, let: { <var_1>: <expression>, ..., <var_n>: <expression> }, pipeline: [ <pipeline to run on the joined collection> ], as: <output array field> } }
參數
-
let:從輸入文件的欄位定義變數的文件。若要在管道階段中參考變數,請使用"$$<variable>"語法。變數可由 中的階段存取pipeline,包括 中巢狀的其他$lookup階段pipeline。$match階段需要使用$expr運算子來存取變數。省略let以執行不相關的子查詢。 -
pipeline:要在from集合上執行的彙總管道。管道無法直接存取輸入文件的欄位;使用 定義變數let,並參考變數。若要傳回所有文件,請指定空管道[]。
將聯結from集合的欄位與let變數或常數進行比較時$eq,放置在$match階段內$expr運算子中的 $gt$gte、$lt、、 和 $lte 比較運算子可以在集合上使用索引。
建立範例文件
db.customers.insertMany([ { _id: 1, name: "Alice", min_total: 60 }, { _id: 2, name: "Bob", min_total: 50 }, { _id: 3, name: "Charlie", min_total: 20 } ]); db.orders.insertMany([ { _id: 1, customer_id: 1, total: 50 }, { _id: 2, customer_id: 1, total: 100 }, { _id: 3, customer_id: 2, total: 75 } ]);
查詢範例
下列範例會將每位客戶與其訂單聯結,並僅保留total大於或等於該客戶自有min_total價值的訂單。聯結條件和每個客戶篩選 內的兩個參考let變數$expr:
db.customers.aggregate([ { $lookup: { from: "orders", let: { customer_id: "$_id", min_total: "$min_total" }, pipeline: [ { $match: { $expr: { $and: [ { $eq: [ "$customer_id", "$$customer_id" ] }, { $gte: [ "$total", "$$min_total" ] } ] } } }, { $project: { _id: 0, total: 1 } } ], as: "qualifying_orders" } } ]);
輸出
[
{ _id: 1, name: 'Alice', min_total: 60, qualifying_orders: [ { total: 100 } ] },
{ _id: 2, name: 'Bob', min_total: 50, qualifying_orders: [ { total: 75 } ] },
{ _id: 3, name: 'Charlie', min_total: 20, qualifying_orders: [] }
]
對於每個客戶,會使用該客戶的 _id和 min_total值評估子查詢,因此每個文件都會收到自己的相關結果。
使用簡潔語法 (MongoDB Shell) 關聯子查詢
8.0.2 版的新功能。
Amazon DocumentDB 也支援簡潔相關的子查詢語法,該語法結合了 localField和 上的等式比對foreignField與 pipeline。簡潔語法會移除在$match階段中的$expr運算子內表達等式比對的需求。
語法
{ $lookup: { from: <collection to join>, localField: <field from the input documents>, foreignField: <field from the documents of the "from" collection>, let: { <var_1>: <expression>, ..., <var_n>: <expression> }, pipeline: [ <pipeline to run> ], as: <output array field> } }
查詢範例
下列範例會傳回與先前相關子查詢範例相同的結果。_id 與 之間的等式比對customer_id會以 localField和 表示,foreignField而非$expr條件:
db.customers.aggregate([ { $lookup: { from: "orders", localField: "_id", foreignField: "customer_id", let: { min_total: "$min_total" }, pipeline: [ { $match: { $expr: { $gte: [ "$total", "$$min_total" ] } } }, { $project: { _id: 0, total: 1 } } ], as: "qualifying_orders" } } ]);
輸出
[
{ _id: 1, name: 'Alice', min_total: 60, qualifying_orders: [ { total: 100 } ] },
{ _id: 2, name: 'Bob', min_total: 50, qualifying_orders: [ { total: 75 } ] },
{ _id: 3, name: 'Charlie', min_total: 20, qualifying_orders: [] }
]
相關子查詢中支援的階段
當$lookup管道使用 時let,下列階段可以參考"$$<variable>"變數:
$match(使用$expr運算子)$project$addFields$set$group$bucket$bucketAuto$sortByCount$lookup(巢狀)$graphLookup
不會評估變數表達式的階段,例如 $sort、、$skip$limit$count、$unwind、、 $sample和 $unset,也可以在管道中使用,但無法參考變數。
使用 let$facet、、$redact、$replaceRoot、$replaceWith、$fill、、 $geoNear $setWindowFields和 $match搭配 的$lookup管道不支援下列階段$text。
限制
-
pipeline不能包含$out或$merge階段。
程式碼範例
若要檢視使用 $lookup命令的程式碼範例,請選擇您要使用的語言標籤:
相關子查詢程式碼範例
若要檢視搭配相關子查詢 (使用 let和 pipeline) 使用$lookup階段的程式碼範例,請選擇您要使用的語言標籤: