

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

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

Baru dari versi 8.0.2.

T `$graphLookup` ahap agregasi di Amazon DocumentDB melakukan pencarian rekursif pada koleksi. Untuk setiap dokumen input, `$graphLookup` dimulai dari satu atau lebih nilai dan berulang kali mencocokkan bidang penghubung ke bidang target, mengikuti rantai dokumen yang cocok sampai tidak ada lagi kecocokan atau kedalaman rekursi opsional tercapai. Ini berguna untuk melintasi data seperti grafik atau hierarkis, seperti struktur pelaporan organisasi, pohon kategori, atau hubungan jaringan.

**Parameter**
+ `from`: Koleksi target untuk mencari secara rekursif. `from`Koleksi harus dalam database yang sama.
+ `startWith`: Ekspresi yang menentukan nilai atau nilai untuk memulai pencarian rekursif. Nilai ini dibandingkan dengan `connectToField` dokumen dalam `from` koleksi. Jika `startWith` dievaluasi ke array, pencarian berjalan dari semua elemen array pada saat yang sama.
+ `connectFromField`: Nama bidang yang nilainya digunakan untuk menghubungkan ke dokumen berikutnya dalam pencarian rekursif. Jika nilainya adalah array, setiap elemen diikuti secara individual melalui traversal.
+ `connectToField`: Nama bidang dalam `from` koleksi yang dicocokkan dengan nilai`connectFromField`.
+ `as`: Nama bidang array ditambahkan ke setiap dokumen keluaran. Bidang ini berisi dokumen yang ditemukan selama pencarian rekursif. Untuk informasi tentang urutan dokumen-dokumen ini, lihat item pemesanan hasil di bagian Perilaku berikut.
+ `maxDepth`: Bilangan bulat non-negatif yang menentukan jumlah maksimum iterasi rekursif yang akan dilakukan setelah pencarian awal. Parameter ini bersifat opsional. Nilai hanya `0` melakukan kecocokan awal dan tidak ada rekursi. Jika Anda menghilangkan`maxDepth`, pencarian berlanjut secara rekursif sampai tidak ada lagi dokumen yang cocok.
+ `depthField`: Nama bidang yang akan ditambahkan ke setiap dokumen dalam `as` array yang menyimpan kedalaman rekursi di mana dokumen ditemukan. Parameter ini bersifat opsional. Kedalaman direpresentasikan sebagai `NumberLong` a dan dimulai dari nol, sehingga pencarian awal sesuai dengan kedalaman`0`.
+ `restrictSearchWithMatch`: Dokumen yang menentukan kondisi kecocokan tambahan yang diterapkan pada dokumen pencarian. Parameter ini bersifat opsional. Kondisi menggunakan sintaks kueri yang sama sebagai `$match` tahap dan tidak dapat menyertakan ekspresi agregasi.

**catatan**  
Pang `$graphLookup` gung tunduk pada batas memori 100 MB dan tidak mendukung`allowDiskUse:true`. Operasi yang melebihi batas ini mengembalikan kesalahan. Jika agregasi mencakup tahapan lain, `allowDiskUse:true` opsi tetap berlaku untuk tahapan tersebut.

**Perilaku **
+ **Cross-collection traversal**: Set `from` el ke koleksi yang ingin Anda cari. Ini bisa berupa koleksi yang sama dengan yang dijalankan pipeline atau koleksi yang berbeda dalam database yang sama.
+ **Urutan hasil**: Dokumen dalam `as` array tidak dikembalikan dalam urutan yang dijamin.

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

Contoh berikut digunakan `$graphLookup` untuk melintasi hierarki pelaporan karyawan dan, untuk setiap karyawan, mengembalikan rantai penuh manajer di atas mereka.

Perintah berikut, jalankan di shell mongosh, masukkan contoh dokumen karyawan yang membentuk hierarki pelaporan:

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

Agregasi berikut mengembalikan rantai manajemen lengkap untuk setiap karyawan dalam `reportingHierarchy` array baru:

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

Operasi ini mengembalikan output berikut:

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

Setiap dokumen karyawan memperoleh `reportingHierarchy` array yang berisi dokumen manajer yang cocok secara rekursif. Bid `level` ang mencatat kedalaman rekursi di mana setiap manajer ditemukan. Asya tidak memiliki `reportsTo` nilai, jadi `reportingHierarchy` ariknya kosong.

## Contoh dengan MaxDepth dan batasi SearchWithMatch (MongoDB Shell)
<a name="graphLookup-filter-depth-example"></a>

Contoh berikut melintasi jaringan koneksi antara orang dan digunakan `maxDepth` untuk membatasi rekursi dan hanya menyertakan `restrictSearchWithMatch` dokumen yang cocok dengan kondisi tambahan. Pencarian menemukan koneksi orang pemula, hingga dua tingkat dalam, hanya menyimpan orang-orang yang mengandung `hobbies` lariknya`golf`.

Perintah berikut, dijalankan di shell mongosh, masukkan dokumen sampel di mana setiap orang `friends` menunjuk ke depan melalui rantai koneksi satu arah:

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

Agregasi berikut dimulai dari Tanya, melintasi jaringan koneksinya hingga dua tingkat dalam, dan hanya menyimpan orang-orang yang terdaftar `golf` sebagai hobi:

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

Operasi ini mengembalikan output berikut:

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

Hanya koneksi yang berisi `hobbies` array yang `golf` disertakan, dan traversal berhenti setelah dua tingkat rekursi. Shirley dikecualikan karena dia tidak mendaftar`golf`, dan Miguel dikecualikan karena dia berjarak tiga tingkat dari Tanya, di `maxDepth` luar. `2` Karena koneksi membentuk rantai satu arah yang tidak pernah menunjuk kembali ke Tanya, dokumen awal tidak cocok selama pencarian rekursif.

## Contoh kode
<a name="graphLookup-code"></a>

Untuk melihat contoh kode yang membangun hierarki pelaporan karyawan dari contoh pertama menggunakan driver MongoDB, pilih tab untuk bahasa yang ingin Anda gunakan:

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

------