你需要採取包括運行使用以下步驟管道聚合管道(順序給出)的方法:
1)$match
以過濾進入管道的文件。考慮使用$in
運營商而不是$or
如果您的表達涉及equality checks for the value of the same field。這與SQL的WHERE
子句類似,例如,代替
SELECT name, images, state, slug
WHERE name in ('Camden', 'Virginia Beach', 'Annapolis')
SELECT name, images, state, slug
WHERE
(name = 'Camden') OR
(name = 'Virginia Beach') OR
(name = 'Annapolis')
2)$lookup
做左外連接到在同一數據庫中的unsharded收集從「接合」在文檔過濾收集這是state
集合進行處理。 $lookup
階段在輸入文檔的state
字段與_id
字段與「已加入」收集狀態的文檔之間執行相等匹配。
3)$unwind
- 從以前$lookup
管道的結果的新領域是一個數組,所以你需要一個$unwind
階段添加到您的管道,以便您可以拼合陣列,因爲它需要作爲非規範化領域進一步處理。
4)$group
管道步驟將所有文檔分組並創建一個數組relatedCities,其中包含來自前一個管道的字段。管道運算符類似於SQL的GROUP BY
子句。在SQL中,除非使用任何聚合函數,否則不能使用GROUP BY
。同樣的,你也必須在MongoDB中使用聚合函數。您可以閱讀關於彙總功能here的更多信息。
您需要創建陣列的累加器運算符爲$push
。
5)$project
最後階段,然後用來選擇或重命名從前面的管道文件的屬性 - 類似於您將與SQL SELECT
條款做什麼。要使用字符串文字創建新字段,您需要運算符,它與SQL的AS
或ALIAS
關鍵字類似。
這裏有一點要注意的是執行管道,MongoDB的管道運營商進入對方時。這裏的「管道」採用Linux的含義:操作員的輸出成爲後面的操作員的輸入。每個操作員的結果都是一個新的文檔集合。所以蒙戈執行上述的管道如下:
collection | $match | $lookup | $unwind | $group | $project => result
現在,當你運行在蒙戈外殼這種聚合管道,其結果將是,當你使用toArray()
方法對cursor
你得到一個數組通過調用aggregate()
方法返回city
集合。
然後,您可以創建首家通過零指數,這是具有聚合領域的新city
文件訪問的唯一元素,結果數組中的city
集合中的新城市條目,並在使用save()
方法城市收藏堅持文件。
下面的例子說明上述概念:
var pipeline = [
{
"$match": {
"name": { "$in": ["Camden", "Virginia Beach", "Annapolis"] }
}
},
{
"$lookup": {
"from": "state",
"localField": "state",
"foreignField": "_id",
"as": "states"
}
},
{ "$unwind": "$states" },
{
"$group": {
"_id": null,
"relatedCities": {
"$push": {
"images": "$images",
"slug": "$slug",
"name": "$name",
"stateSlug": "$states.slug"
}
}
}
},
{
"$project": {
"_id": 0,
"name": { "$literal": "Lewes" },
"relatedCities": 1
}
}
],
newCity = db.city.aggregate(pipeline).toArray()[0];
db.city.save(newCity);