本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
$graphLookup
8.0.2 版的新功能。
Amazon DocumentDB $graphLookup 中的彙總階段會對集合執行遞迴搜尋。對於每個輸入文件, 會從一或多個值$graphLookup開始,並重複比對連線欄位與目標欄位,遵循相符文件鏈,直到沒有更多相符項目或達到選用的遞迴深度為止。這適用於周遊類似圖形或階層的資料,例如組織報告結構、類別樹或網路關係。
參數
-
from:遞迴搜尋的目標集合。from集合必須位於相同的資料庫中。 -
startWith:指定用來開始遞迴搜尋之值的表達式。此值會與from集合中文件connectToField的 進行比較。如果startWith評估為 陣列,則搜尋會同時從所有陣列元素執行。 -
connectFromField:其值用於連線到遞迴搜尋中下一個文件的欄位名稱。如果該值是陣列,則每個元素都會透過周遊個別追蹤。 -
connectToField:from集合中與 值相符的欄位名稱connectFromField。 -
as:新增至每個輸出文件的陣列欄位名稱。此欄位包含在遞迴搜尋期間找到的文件。如需這些文件順序的資訊,請參閱下列行為區段中的結果排序項目。 -
maxDepth:非負整數,指定初始查詢後要執行的遞迴反覆運算數目上限。此為選用參數。的值只會0執行初始比對,不會遞迴。如果您省略maxDepth,搜尋會持續遞迴搜尋,直到沒有更多相符的文件為止。 -
depthField:要新增至as陣列中每個文件的欄位名稱,該文件包含找到文件的遞迴深度。此為選用參數。深度以 表示NumberLong,從零開始,因此初始查詢對應至深度0。 -
restrictSearchWithMatch:指定套用至搜尋文件之其他比對條件的文件。此為選用參數。條件使用與$match階段相同的查詢語法,且不能包含彙總表達式。
注意
$graphLookup 階段受限於 100 MB 的記憶體限制,且不支援 allowDiskUse:true。超過此限制的操作會傳回錯誤。如果彙總包含其他階段,則這些階段allowDiskUse:true的選項仍然有效。
行為
-
跨集合周遊:
from設定為您要搜尋的集合。這可以是管道執行的相同集合,或相同資料庫中的不同集合。 -
結果排序:
as陣列中的文件不會以任何保證順序傳回。
範例 (MongoDB Shell)
下列範例使用 $graphLookup來周遊員工報告階層,並針對每個員工傳回上述的完整經理鏈。
下列命令會在 mongosh shell 中執行,插入建立報告階層的範例員工文件:
db.employees.insertMany([ { _id: 1, name: "Dev", reportsTo: "Eliot" }, { _id: 2, name: "Eliot", reportsTo: "Ron" }, { _id: 3, name: "Ron", reportsTo: "Andrew" }, { _id: 4, name: "Andrew", reportsTo: "Asya" }, { _id: 5, name: "Asya" } ]);
下列彙總會傳回新reportingHierarchy陣列中每個員工的完整管理鏈:
db.employees.aggregate([ { $graphLookup: { from: "employees", startWith: "$reportsTo", connectFromField: "reportsTo", connectToField: "name", as: "reportingHierarchy", depthField: "level" } } ]);
此操作會傳回下列輸出:
[
{
_id: 1,
name: 'Dev',
reportsTo: 'Eliot',
reportingHierarchy: [
{ _id: 2, name: 'Eliot', reportsTo: 'Ron', level: 0 },
{ _id: 3, name: 'Ron', reportsTo: 'Andrew', level: 1 },
{ _id: 4, name: 'Andrew', reportsTo: 'Asya', level: 2 },
{ _id: 5, name: 'Asya', level: 3 }
]
},
{
_id: 2,
name: 'Eliot',
reportsTo: 'Ron',
reportingHierarchy: [
{ _id: 3, name: 'Ron', reportsTo: 'Andrew', level: 0 },
{ _id: 4, name: 'Andrew', reportsTo: 'Asya', level: 1 },
{ _id: 5, name: 'Asya', level: 2 }
]
},
{
_id: 3,
name: 'Ron',
reportsTo: 'Andrew',
reportingHierarchy: [
{ _id: 4, name: 'Andrew', reportsTo: 'Asya', level: 0 },
{ _id: 5, name: 'Asya', level: 1 }
]
},
{
_id: 4,
name: 'Andrew',
reportsTo: 'Asya',
reportingHierarchy: [
{ _id: 5, name: 'Asya', level: 0 }
]
},
{
_id: 5,
name: 'Asya',
reportingHierarchy: []
}
]
每個員工文件都會取得陣列reportingHierarchy,其中包含遞迴比對的管理員文件。level 欄位會記錄找到每個管理員的遞迴深度。Asya 沒有reportsTo值,因此她的reportingHierarchy陣列是空的。
maxDepth 和 restrictSearchWithMatch (MongoDB Shell) 的範例
下列範例會周遊人員與 之間的連線網路maxDepth,以限制遞迴restrictSearchWithMatch,並僅包含符合其他條件的文件。搜尋會尋找起始人員的連線,最多兩個層級深度,只保留hobbies陣列包含 的人員golf。
下列命令在 mongosh shell 中執行,插入範例文件,其中每個人的friends點都透過單向連線鏈向前:
db.people.insertMany([ { _id: 1, name: "Tanya", friends: [ "Carole", "Shirley" ], hobbies: [ "tennis", "golf" ] }, { _id: 2, name: "Carole", friends: [ "Joseph" ], hobbies: [ "archery", "golf" ] }, { _id: 3, name: "Joseph", friends: [ "Angelo" ], hobbies: [ "tennis", "golf" ] }, { _id: 4, name: "Angelo", friends: [ "Miguel" ], hobbies: [ "travel", "golf" ] }, { _id: 5, name: "Miguel", friends: [], hobbies: [ "golf" ] }, { _id: 6, name: "Shirley", friends: [], hobbies: [ "frisbee" ] } ]);
下列彙總從 Tanya 開始,會周遊她的連線網路最多兩個層級深度,並僅保留列出golf為愛好的人員:
db.people.aggregate([ { $match: { name: "Tanya" } }, { $graphLookup: { from: "people", startWith: "$friends", connectFromField: "friends", connectToField: "name", as: "golfConnections", maxDepth: 2, restrictSearchWithMatch: { hobbies: "golf" } } }, { $project: { name: 1, "golfConnections.name": 1 } } ]);
此操作會傳回下列輸出:
[
{
_id: 1,
name: 'Tanya',
golfConnections: [
{ name: 'Carole' },
{ name: 'Joseph' },
{ name: 'Angelo' }
]
}
]
只有hobbies陣列包含 的連線golf才會包含在內,而周遊會在兩個遞迴層級後停止。Shirley 會被排除,因為她未列出 golf,而 Miguel 會被排除,因為他離 Tanya 有三個關卡,超過 maxDepth的 2。由於連線形成的單向鏈永遠不會指向 Tanya,因此開始文件在遞迴搜尋期間不相符。
程式碼範例
若要檢視使用 MongoDB 驅動程式從第一個範例建置員工報告階層的程式碼範例,請選擇您要使用的語言標籤: