View a markdown version of this page

$graphLookup - Amazon DocumentDB

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

$graphLookup

Neu ab Version 8.0.2.

Die $graphLookup Aggregationsphase in Amazon DocumentDB führt eine rekursive Suche in einer Sammlung durch. $graphLookupBeginnt bei jedem Eingabedokument mit einem oder mehreren Werten und ordnet wiederholt ein Verbindungsfeld einem Zielfeld zu. Dabei folgt man der Kette übereinstimmender Dokumente, bis keine Treffer mehr vorliegen oder eine optionale Rekursionstiefe erreicht ist. Dies ist nützlich, wenn Sie grafische oder hierarchische Daten wie organisatorische Berichtsstrukturen, Kategorienbäume oder Netzwerkbeziehungen durchsuchen möchten.

Parameter

  • from: Die Zielsammlung, nach der rekursiv gesucht werden soll. Die from Sammlung muss sich in derselben Datenbank befinden.

  • startWith: Der Ausdruck, der den oder die Werte angibt, mit denen die rekursive Suche beginnen soll. Dieser Wert wird mit dem connectToField der Dokumente in der from Sammlung verglichen. Wenn startWith die Auswertung zu einem Array führt, wird die Suche für alle Array-Elemente gleichzeitig ausgeführt.

  • connectFromField: Der Feldname, dessen Wert verwendet wird, um bei der rekursiven Suche eine Verbindung zum nächsten Dokument herzustellen. Handelt es sich bei dem Wert um ein Array, wird jedes Element einzeln beim Durchlauf verfolgt.

  • connectToField: Der Feldname in der from Sammlung, der mit dem Wert von abgeglichen wird. connectFromField

  • as: Der Name des Array-Felds, das jedem Ausgabedokument hinzugefügt wurde. Dieses Feld enthält die Dokumente, die bei der rekursiven Suche gefunden wurden. Informationen zur Reihenfolge dieser Dokumente finden Sie unter dem Element Reihenfolge der Ergebnisse im folgenden Abschnitt Verhalten.

  • maxDepth: Eine nicht negative Ganzzahl, die die maximale Anzahl rekursiver Iterationen angibt, die nach der ersten Suche ausgeführt werden sollen. Dieser Parameter ist optional. Mit dem Wert von wird nur 0 die erste Übereinstimmung und keine Rekursion durchgeführt. Wenn Sie diesen Wert weglassenmaxDepth, wird die Suche rekursiv fortgesetzt, bis keine passenden Dokumente mehr gefunden werden.

  • depthField: Der Name des Felds, das zu jedem Dokument in dem as Array hinzugefügt werden soll, das die Rekursionstiefe enthält, in der das Dokument gefunden wurde. Dieser Parameter ist optional. Die Tiefe wird als a dargestellt NumberLong und beginnt bei Null, sodass die anfängliche Suche einer Tiefe von 0 entspricht.

  • restrictSearchWithMatch: Ein Dokument, das eine zusätzliche Übereinstimmungsbedingung festlegt, die auf die Dokumente der Suche angewendet wird. Dieser Parameter ist optional. Die Bedingung verwendet dieselbe Abfragesyntax wie eine $match Stufe und kann keine Aggregationsausdrücke enthalten.

Anmerkung

Der $graphLookup Stagingbereich unterliegt einer Speicherbeschränkung von 100 MB und wird nicht unterstütztallowDiskUse:true. Ein Vorgang, der dieses Limit überschreitet, gibt einen Fehler zurück. Wenn die Aggregation andere Stufen umfasst, bleibt die allowDiskUse:true Option für diese Stufen gültig.

Behavior

  • Cross-collection Traversal: Wählen Sie die Sammlung ausfrom, die Sie durchsuchen möchten. Dies kann dieselbe Sammlung sein, mit der die Pipeline läuft, oder eine andere Sammlung in derselben Datenbank.

  • Reihenfolge der Ergebnisse: Die Dokumente im as Array werden nicht in einer garantierten Reihenfolge zurückgegeben.

Beispiel (MongoDB Shell)

Im folgenden Beispiel wird $graphLookup eine Berichtshierarchie für Mitarbeiter durchquert und für jeden Mitarbeiter die gesamte Kette der Manager über ihm zurückgegeben.

Die folgenden Befehle, die in der Mongosh-Shell ausgeführt werden, fügen Beispieldokumente für Mitarbeiter ein, die eine Berichtshierarchie festlegen:

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" } ]);

Die folgende Aggregation gibt die vollständige Verwaltungskette für jeden Mitarbeiter in einem neuen reportingHierarchy Array zurück:

db.employees.aggregate([ { $graphLookup: { from: "employees", startWith: "$reportsTo", connectFromField: "reportsTo", connectToField: "name", as: "reportingHierarchy", depthField: "level" } } ]);

Dieser Vorgang gibt die folgende Ausgabe zurück:

[ { _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: [] } ]

Jedes Mitarbeiterdokument erhält ein reportingHierarchy Array, das die rekursiv abgeglichenen Managerdokumente enthält. Das level Feld zeichnet die Rekursionstiefe auf, bei der jeder Manager gefunden wurde. Asya hat keinen reportsTo Wert, daher ist ihr reportingHierarchy Array leer.

Beispiel mit MaxDepth und Restrict SearchWithMatch (MongoDB Shell)

Das folgende Beispiel durchquert ein Netzwerk von Verbindungen zwischen Personen und verwendet, um die Rekursion maxDepth zu begrenzen und nur Dokumente restrictSearchWithMatch einzubeziehen, die eine zusätzliche Bedingung erfüllen. Bei der Suche werden die Verbindungen einer Startperson mit einer Tiefe von bis zu zwei Ebenen gefunden, wobei nur Personen angezeigt werden, deren hobbies Array Folgendes enthält. golf

Die folgenden Befehle, die in der Mongosh-Shell ausgeführt werden, fügen Beispieldokumente ein, in denen jede Person friends durch eine eindirektionale Verbindungskette nach vorne zeigt:

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" ] } ]);

Die folgende Aggregation beginnt bei Tanya, durchquert ihr bis zu zwei Ebenen tiefes Netzwerk von Verbindungen und führt nur die Personen, die diese Liste als Hobby auflisten: 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 } } ]);

Dieser Vorgang gibt die folgende Ausgabe zurück:

[ { _id: 1, name: 'Tanya', golfConnections: [ { name: 'Carole' }, { name: 'Joseph' }, { name: 'Angelo' } ] } ]

Nur Verbindungen, deren hobbies Array Folgendes enthält, golf sind enthalten, und das Durchlaufen wird nach zwei Rekursionsebenen beendet. Shirley ist ausgeschlossen, weil sie nichts auflistetgolf, und Miguel ist ausgeschlossen, weil er drei Stufen von Tanya entfernt ist, hinter dem von. maxDepth 2 Da die Verbindungen eine unidirektionale Kette bilden, die niemals auf Tanya zurückweist, wird das Ausgangsdokument bei der rekursiven Suche nicht gefunden.

Codebeispiele

Um ein Codebeispiel anzuzeigen, das die Berichtshierarchie für Mitarbeiter anhand des ersten Beispiels mithilfe eines MongoDB-Treibers aufbaut, wählen Sie die Registerkarte für die Sprache, die Sie verwenden möchten:

Node.js
const { MongoClient } = require('mongodb'); async function example() { const client = new MongoClient('mongodb://<username>:<password>@<cluster-endpoint>:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false'); try { await client.connect(); const db = client.db('test'); const employees = db.collection('employees'); const result = await employees.aggregate([ { $graphLookup: { from: 'employees', startWith: '$reportsTo', connectFromField: 'reportsTo', connectToField: 'name', as: 'reportingHierarchy', depthField: 'level' } } ]).toArray(); console.log(JSON.stringify(result, null, 2)); } catch (err) { console.error('Failed to run $graphLookup aggregation:', err.message); } finally { await client.close(); } } example();
Python
from pymongo import MongoClient from pymongo.errors import PyMongoError def example(): client = MongoClient('mongodb://<username>:<password>@<cluster-endpoint>:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false') try: db = client['test'] employees = db['employees'] pipeline = [ { "$graphLookup": { "from": "employees", "startWith": "$reportsTo", "connectFromField": "reportsTo", "connectToField": "name", "as": "reportingHierarchy", "depthField": "level" } } ] result = list(employees.aggregate(pipeline)) for doc in result: print(doc) except PyMongoError as error: print(f"Failed to run $graphLookup aggregation: {error}") finally: client.close() example()