

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# $graphLookup
<a name="graphLookup"></a>

Nuovo dalla versione 8.0.2.

La fase di `$graphLookup` aggregazione in Amazon DocumentDB esegue una ricerca ricorsiva su una raccolta. Per ogni documento di input, `$graphLookup` parte da uno o più valori e abbina ripetutamente un campo di connessione a un campo di destinazione, seguendo la catena di documenti corrispondenti fino a quando non ci sono più corrispondenze o viene raggiunta una profondità di ricorsione opzionale. Ciò è utile per attraversare dati gerarchici o simili a grafici, come strutture di reporting organizzativo, alberi di categorie o relazioni di rete.

**Parametri**
+ `from`: la raccolta di destinazione da cercare in modo ricorsivo. La `from` raccolta deve trovarsi nello stesso database.
+ `startWith`: L'espressione che specifica il valore o i valori con cui iniziare la ricerca ricorsiva. Questo valore viene confrontato con quello `connectToField` dei documenti della raccolta. `from` Se `startWith` restituisce un array, la ricerca viene eseguita da tutti gli elementi dell'array contemporaneamente.
+ `connectFromField`: il nome del campo il cui valore viene utilizzato per connettersi al documento successivo nella ricerca ricorsiva. Se il valore è un array, ogni elemento viene seguito singolarmente durante l'attraversamento.
+ `connectToField`: il nome del campo nella `from` raccolta che viene confrontato con il valore di. `connectFromField`
+ `as`: il nome del campo dell'array aggiunto a ciascun documento di output. Questo campo contiene i documenti trovati durante la ricerca ricorsiva. Per informazioni sull'ordine di questi documenti, vedere la voce Ordinamento dei risultati nella seguente sezione Comportamento.
+ `maxDepth`: un numero intero non negativo che specifica il numero massimo di iterazioni ricorsive da eseguire dopo la ricerca iniziale. Questo parametro è facoltativo. Un valore di `0` esegue solo la corrispondenza iniziale e nessuna ricorsione. Se si omette`maxDepth`, la ricerca continua in modo ricorsivo fino a quando non ci sono più documenti corrispondenti.
+ `depthField`: il nome del campo da aggiungere a ciascun documento dell'`as`array che contiene la profondità di ricorsione alla quale il documento è stato trovato. Questo parametro è facoltativo. La profondità è rappresentata come a `NumberLong` e parte da zero, quindi la ricerca iniziale corrisponde a una profondità di. `0`
+ `restrictSearchWithMatch`: Un documento che specifica un'ulteriore condizione di corrispondenza applicata ai documenti della ricerca. Questo parametro è facoltativo. La condizione utilizza la stessa sintassi di interrogazione di una `$match` fase e non può includere espressioni di aggregazione.

**Nota**  
Lo `$graphLookup` stage è soggetto a un limite di memoria di 100 MB e non supporta. `allowDiskUse:true` Un'operazione che supera questo limite restituisce un errore. Se l'aggregazione include altre fasi, l'`allowDiskUse:true`opzione rimane valida per tali fasi.

**Comportamento**
+ **Cross-collection attraversamento**: imposta la raccolta `from` in cui desideri cercare. Può trattarsi della stessa raccolta su cui viene eseguita la pipeline o di una raccolta diversa nello stesso database.
+ **Ordinamento dei risultati**: i documenti dell'`as`array non vengono restituiti in alcun ordine garantito.

## Esempio (MongoDB Shell)
<a name="graphLookup-examples"></a>

L'esempio seguente viene utilizzato `$graphLookup` per attraversare una gerarchia di rendicontazione dei dipendenti e, per ogni dipendente, restituire l'intera catena di manager che li precede.

I seguenti comandi, eseguiti nella shell mongosh, inseriscono documenti di esempio per i dipendenti che stabiliscono una gerarchia di reporting:

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

La seguente aggregazione restituisce l'intera catena di gestione per ogni dipendente in un nuovo array: `reportingHierarchy`

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

Questa operazione restituisce il seguente risultato:

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

Ogni documento del dipendente ottiene un `reportingHierarchy` array che contiene i documenti del manager abbinati in modo ricorsivo. Il `level` campo registra la profondità di ricorsione alla quale è stato trovato ciascun manager. Asya non ha alcun `reportsTo` valore, quindi il suo `reportingHierarchy` array è vuoto.

## Esempio con MaxDepth e restrict SearchWithMatch (MongoDB Shell)
<a name="graphLookup-filter-depth-example"></a>

L'esempio seguente attraversa una rete di connessioni tra persone e utilizza `maxDepth` per limitare la ricorsione e includere solo i documenti che soddisfano una `restrictSearchWithMatch` condizione aggiuntiva. La ricerca trova le connessioni di una persona iniziale, con una profondità massima di due livelli, mantenendo solo le persone il cui array contiene. `hobbies` `golf`

I seguenti comandi, eseguiti nella shell mongosh, inseriscono documenti di esempio in cui ogni persona `friends` punta in avanti attraverso una catena di connessioni unidirezionale:

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

La seguente aggregazione parte da Tanya, attraversa la sua rete di connessioni fino a due livelli di profondità e mantiene solo le persone inserite nell'elenco per hobby: `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 } }
]);
```

Questa operazione restituisce il seguente risultato:

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

`golf`Sono incluse solo le connessioni il cui `hobbies` array contiene e l'attraversamento si interrompe dopo due livelli di ricorsione. Shirley è esclusa perché non figura nell'elenco`golf`, e Miguel è escluso perché si trova a tre livelli da Tanya, oltre il limite del. `maxDepth` `2` Poiché le connessioni formano una catena unidirezionale che non rimanda mai a Tanya, il documento iniziale non corrisponde durante la ricerca ricorsiva.

## Esempi di codice
<a name="graphLookup-code"></a>

Per visualizzare un esempio di codice che crea la gerarchia dei report per i dipendenti a partire dal primo esempio utilizzando un driver MongoDB, scegli la scheda relativa alla lingua che desideri utilizzare:

------
#### [ 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()
```

------