

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

# Mengakses grafik Neptune dengan Gremlin
<a name="access-graph-gremlin"></a>

Amazon Neptunus kompatibel dengan TinkerPop Apache dan Gremlin. Ini berarti Anda dapat terhubung ke instans DB Neptunus dan menggunakan bahasa traversal Gremlin untuk menanyakan grafik ([lihat](https://tinkerpop.apache.org/docs/current/reference/#graph) Grafik dalam dokumentasi Apache). TinkerPop Untuk perbedaan dalam implementasi Neptune Gremlin, lihat [Kepatuhan standar Gremlin](access-graph-gremlin-differences.md).

 Sebuah *traversal* di Gremlin adalah serangkaian langkah berantai. Traversal dimulai pada sebuah vertex (atau edge). Traversal menelusuri grafik dengan mengikuti edge keluar dari setiap vertex lalu edge keluar dari vertex tersebut. Setiap langkah adalah operasi dalam traversal. Untuk informasi selengkapnya, lihat [The Traversal](https://tinkerpop.apache.org/docs/current/reference/#traversal) dalam TinkerPop dokumentasi.

Versi mesin Neptune yang berbeda mendukung versi Gremlin yang berbeda. Periksa [halaman rilis mesin](engine-releases.md) versi Neptunus yang Anda jalankan untuk menentukan rilis Gremlin mana yang didukungnya atau lihat tabel berikut yang mencantumkan versi paling awal dan terbaru yang TinkerPop didukung oleh versi mesin Neptunus yang berbeda:


| Versi Mesin Neptune |  TinkerPop Versi Minimum |  TinkerPop Versi Maksimum | 
| --- | --- | --- | 
| `1.3.2.0 and newer` | `3.7.1` | `3.7.3` | 
| `1.3.1.0` | `3.6.2` | `3.6.5` | 
| `1.3.0.0` | `3.6.2` | `3.6.4` | 
| `1.2.1.0 <= 1.2.1.2` | `3.6.2` | `3.6.2` | 
| `1.1.1.0 <= 1.2.0.2` | `3.5.5` | `3.5.6` | 
| `1.1.0.0 and older` | `(deprecated)` | `(deprecated)` | 

TinkerPop klien biasanya kompatibel ke belakang dalam seri (`3.6.x`, misalnya, atau`3.7.x`) dan sementara mereka sering dapat bekerja melintasi batas-batas tersebut, tabel di atas merekomendasikan kombinasi versi untuk digunakan untuk pengalaman dan kompatibilitas terbaik. Kecuali disarankan lain, umumnya yang terbaik adalah mematuhi pedoman ini dan meningkatkan aplikasi klien agar sesuai dengan versi yang TinkerPop Anda gunakan.

Saat memutakhirkan TinkerPop versi, selalu penting untuk merujuk ke [TinkerPopdokumentasi pemutakhiran](http://tinkerpop.apache.org/docs/current/upgrade/) yang akan membantu Anda mengidentifikasi fitur baru yang dapat Anda manfaatkan, tetapi juga masalah yang mungkin perlu Anda waspadai saat mendekati peningkatan. Anda biasanya mengharapkan kueri dan fitur yang ada berfungsi setelah peningkatan kecuali sesuatu secara khusus disebut sebagai masalah untuk dipertimbangkan. Terakhir, penting untuk dicatat bahwa jika versi yang Anda tingkatkan untuk memiliki fitur baru, Anda mungkin tidak dapat menggunakannya jika berasal dari versi yang lebih lambat dari yang didukung Neptunus.

Ada beberapa varian bahasa Gremlin dan dukungan untuk akses Gremlin dalam berbagai bahasa pemrograman. Untuk informasi selengkapnya, lihat [Tentang Varian Bahasa Gremlin](https://tinkerpop.apache.org/docs/current/reference/#gremlin-drivers-variants) dalam dokumentasi. TinkerPop 

Dokumentasi ini menjelaskan cara mengakses Neptunus dengan varian dan bahasa pemrograman berikut:
+ [Mengatur konsol Gremlin agar terhubung ke instans DB Neptune](access-graph-gremlin-console.md)
+ [Menggunakan titik akhir HTTPS REST untuk menyambung ke instans DB Neptune](access-graph-gremlin-rest.md)
+ [Klien Gremlin berbasis Java untuk digunakan dengan Amazon Neptunus](access-graph-gremlin-client.md)
+ [Menggunakan Python untuk terhubung ke instans DB Neptune](access-graph-gremlin-python.md)
+ [Gunakan .NET untuk terhubung ke instans DB Neptune](access-graph-gremlin-dotnet.md)
+ [Gunakan Node.js untuk terhubung ke instans DB Neptune](access-graph-gremlin-node-js.md)
+ [Menggunakan Go untuk terhubung ke instans DB Neptunus](access-graph-gremlin-go.md)

Seperti dibahas dalam[Mengenkripsi koneksi ke database Amazon Neptunus Anda dengan SSL/HTTPS](security-ssl.md), Anda harus menggunakan Transport Layer Security/Secure Sockets Layer (TLS/SSL) saat menghubungkan ke Neptunus di semua Wilayah. AWS 

Sebelum Anda mulai, Anda harus memiliki yang berikut:
+ Instans DB Neptune. Untuk informasi tentang membuat instans DB Neptune, lihat [Membuat cluster Amazon Neptunus](get-started-create-cluster.md).
+ Instans Amazon EC2 di virtual private cloud (VPC) yang sama seperti instans DB Neptune Anda.

Untuk informasi lebih lanjut tentang memuat data ke dalam Neptune, termasuk prasyarat, format pemuatan, dan parameter beban, lihat [Memuat data ke Amazon Neptune](load-data.md).

**Topics**
+ [

# Mengatur konsol Gremlin agar terhubung ke instans DB Neptune
](access-graph-gremlin-console.md)
+ [

# Menggunakan titik akhir HTTPS REST untuk menyambung ke instans DB Neptune
](access-graph-gremlin-rest.md)
+ [

# Klien Gremlin berbasis Java untuk digunakan dengan Amazon Neptunus
](access-graph-gremlin-client.md)
+ [

# Menggunakan Python untuk terhubung ke instans DB Neptune
](access-graph-gremlin-python.md)
+ [

# Gunakan .NET untuk terhubung ke instans DB Neptune
](access-graph-gremlin-dotnet.md)
+ [

# Gunakan Node.js untuk terhubung ke instans DB Neptune
](access-graph-gremlin-node-js.md)
+ [

# Menggunakan Go untuk terhubung ke instans DB Neptunus
](access-graph-gremlin-go.md)
+ [

# Menggunakan AWS SDK untuk menjalankan kueri Gremlin
](access-graph-gremlin-sdk.md)
+ [

# Petunjuk kueri Gremlin
](gremlin-query-hints.md)
+ [

# API status kueri Gremlin
](gremlin-api-status.md)
+ [

# Pembatalan kueri Gremlin
](gremlin-api-status-cancel.md)
+ [

# Support untuk sesi berbasis skrip Gremlin
](access-graph-gremlin-sessions.md)
+ [

# Transaksi Gremlin di Neptunus
](access-graph-gremlin-transactions.md)
+ [

# Menggunakan API Gremlin dengan Amazon Neptune
](gremlin-api-reference.md)
+ [

# Hasil kueri cache di Amazon Neptunus Gremlin
](gremlin-results-cache.md)
+ [

# Membuat peningkatan yang efisien dengan `mergeV()` Gremlin dan langkah-langkah `mergeE()`
](gremlin-efficient-upserts.md)
+ [

# Membuat peningkatan Gremlin yang efisien dengan `fold()/coalesce()/unfold()`
](gremlin-efficient-upserts-pre-3.6.md)
+ [

# Menganalisis eksekusi kueri Neptune menggunakan `explain` Gremlin
](gremlin-explain.md)
+ [

# Menggunakan Gremlin dengan mesin kueri Neptunus DFE
](gremlin-with-dfe.md)

# Mengatur konsol Gremlin agar terhubung ke instans DB Neptune
<a name="access-graph-gremlin-console"></a>

Konsol Gremlin memungkinkan Anda bereksperimen dengan TinkerPop grafik dan kueri di lingkungan REPL (loop). read-eval-print 

## Menginstal konsol Gremlin dan menghubungkannya dengan cara biasa
<a name="access-graph-gremlin-console-usual-connect"></a>

Anda dapat menggunakan Konsol Gremlin untuk terhubung ke basis data grafik jarak jauh. Bagian berikut memandu Anda melalui penginstalan dan konfigurasi Konsol Gremlin untuk menghubungkan ke instans DB Neptune secara jarak jauh. Anda harus mengikuti petunjuk ini dari instans Amazon EC2 di virtual private cloud (VPC) yang sama seperti instans DB Neptune Anda.

Untuk bantuan menghubungkan ke Neptunus SSL/TLS dengan (yang diperlukan), lihat. [Konfigurasi SSL/TLS](access-graph-gremlin-java.md#access-graph-gremlin-java-ssl)

**catatan**  
Jika [autentikasi IAM diaktifkan](iam-auth-enable.md) di cluster DB Neptunus Anda, ikuti petunjuk [Menghubungkan ke database Amazon Neptunus menggunakan otentikasi IAM dengan konsol Gremlin](iam-auth-connecting-gremlin-console.md) untuk menginstal konsol Gremlin daripada instruksi di sini.

**Untuk memasang Konsol Gremlin dan menyambung ke Neptune**

1. Biner Konsol Gremlin memerlukan Java 8 atau Java 11. Instruksi ini mengasumsikan penggunaan Java 11. Anda dapat menginstal Java 11 pada instans EC2 Anda sebagai berikut:
   + Jika Anda menggunakan [Amazon Linux 2 (AL2)](https://aws.amazon.com/amazon-linux-2):

     ```
     sudo amazon-linux-extras install java-openjdk11
     ```
   + Jika Anda menggunakan [Amazon Linux 2023 (AL2023)](https://docs.aws.amazon.com/linux/al2023/ug/what-is-amazon-linux.html):

     ```
     sudo yum install java-11-amazon-corretto-devel
     ```
   + Untuk distribusi lain, gunakan salah satu dari berikut ini yang sesuai:

     ```
     sudo yum install java-11-openjdk-devel
     ```

     atau:

     ```
     sudo apt-get install openjdk-11-jdk
     ```

1. Masukkan yang berikut ini untuk mengatur Java 11 sebagai runtime default pada instans EC2 Anda.

   ```
   sudo /usr/sbin/alternatives --config java
   ```

   Saat diminta, masukkan nomor untuk Java 11.

1. Unduh versi Konsol Gremlin yang sesuai dari situs web Apache. Anda dapat memeriksa versi Gremlin mana yang didukung versi Neptunus Anda. [Mengakses grafik Neptune dengan Gremlin](access-graph-gremlin.md) Misalnya, jika Anda memerlukan versi 3.7.2, Anda dapat mengunduh [konsol Gremlin](https://archive.apache.org/dist/tinkerpop/3.7.2/apache-tinkerpop-gremlin-console-3.7.2-bin.zip) dari situs web [Apache Tinkerpop](https://tinkerpop.apache.org/download.html) ke instans EC2 Anda seperti ini:

   ```
   wget https://archive.apache.org/dist/tinkerpop/3.7.2/apache-tinkerpop-gremlin-console-3.7.2-bin.zip
   ```

1. Unzip file Konsol Gremlin.

   ```
   unzip apache-tinkerpop-gremlin-console-3.7.2-bin.zip
   ```

1. Ubah direktori ke dalam direktori yang di-unzip.

   ```
   cd apache-tinkerpop-gremlin-console-3.7.2
   ```

1. Di sudirektori `conf` dari direktori yang diekstrak, buat sebuah file bernama `neptune-remote.yaml` dengan teks berikut. Ganti *your-neptune-endpoint* dengan nama host atau alamat IP instans DB Neptunus Anda. Tanda kurung persegi (`[ ]`) wajib diisi.
**catatan**  
Untuk informasi tentang menemukan nama host instans DB Neptune Anda, lihat bagian [Menghubungkan ke Titik Akhir Amazon Neptune.](feature-overview-endpoints.md).

   ```
   hosts: [your-neptune-endpoint]
   port: 8182
   connectionPool: { enableSsl: true }
   serializer: { className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1,
                 config: { serializeResultToString: true }}
   ```
**catatan**  
 Serializer dipindahkan dari `gremlin-driver` modul ke `gremlin-util` modul baru di versi 3.7.0. Paket diubah dari org.apache.tinkerpop.gremlin.driver.ser menjadi org.apache.tinkerpop.gremlin.util.ser. 

1. Di terminal, bernavigasilah ke direktori Konsol Gremlin (`apache-tinkerpop-gremlin-console-3.7.2`), lalu masukkan perintah berikut untuk menjalankan Konsol Gremlin.

   ```
   bin/gremlin.sh
   ```

   Anda akan melihat output berikut:

   ```
            \,,,/
            (o o)
   -----oOOo-(3)-oOOo-----
   plugin activated: tinkerpop.server
   plugin activated: tinkerpop.utilities
   plugin activated: tinkerpop.tinkergraph
   gremlin>
   ```

   Anda sekarang berada di prompt `gremlin>`. Anda akan memasukkan langkah-langkah yang tersisa pada prompt ini.

1. Di prompt `gremlin>`, masukkan hal berikut untuk menyambung ke instans DB Neptune.

   ```
   :remote connect tinkerpop.server conf/neptune-remote.yaml
   ```

1. Di prompt `gremlin>`, masukkan hal berikut ini untuk beralih ke mode jarak jauh. Ini mengirimkan semua kueri Gremlin ke koneksi remote.

   ```
   :remote console
   ```

1. Masukkan hal berikut untuk mengirim kueri ke Gremlin Graph.

   ```
   g.V().limit(1)
   ```

1. Setelah Anda selesai, masukkan hal berikut untuk keluar dari Konsol Gremlin.

   ```
   :exit
   ```

**catatan**  
Gunakan titik koma (`;`) atau karakter baris baru (`\n`) untuk memisahkan setiap pernyataan.   
Setiap traversal sebelum traversal akhir harus diakhiri dengan `next()` yang akan dieksekusi. Hanya data dari traversal akhir yang dikembalikan.

Untuk informasi lebih lanjut tentang implementasi Neptune dari Gremlin, lihat [Kepatuhan standar Gremlin di Amazon Neptune](access-graph-gremlin-differences.md).

# Cara alternatif untuk terhubung ke konsol Gremlin
<a name="access-graph-gremlin-console-connect"></a>

**Kelemahan dari pendekatan koneksi normal**

Cara paling umum untuk terhubung ke konsol Gremlin adalah yang dijelaskan di atas, menggunakan perintah seperti ini pada `gremlin>` prompt:

```
gremlin> :remote connect tinkerpop.server conf/(file name).yaml
gremlin> :remote console
```

Ini berfungsi dengan baik, dan memungkinkan Anda mengirim kueri ke Neptunus. Namun, itu mengeluarkan mesin skrip Groovy dari loop, jadi Neptunus memperlakukan semua kueri sebagai Gremlin murni. Ini berarti bahwa formulir kueri berikut gagal:

```
gremlin> 1 + 1
gremlin> x = g.V().count()
```

Yang paling dekat yang bisa Anda dapatkan menggunakan variabel saat terhubung dengan cara ini adalah dengan menggunakan `result` variabel yang dikelola oleh konsol dan mengirim kueri menggunakan`:>`, seperti ini:

```
gremlin> :remote console
==>All scripts will now be evaluated locally - type ':remote console' to return to remote mode for Gremlin Server - [krl-1-cluster.cluster-ro-cm9t6tfwbtsr.us-east-1.neptune.amazonaws.com/172.31.19.217:8182]
gremlin> :> g.V().count()
==>4249

gremlin> println(result)
[result{object=4249 class=java.lang.Long}]

gremlin> println(result['object'])
[4249]
```

 

**Cara berbeda untuk terhubung**

Anda juga dapat terhubung ke konsol Gremlin dengan cara yang berbeda, yang mungkin Anda temukan lebih bagus, seperti ini:

```
gremlin> g = traversal().withRemote('conf/neptune.properties')
```

Di sini `neptune.properties` mengambil formulir ini:

```
gremlin.remote.remoteConnectionClass=org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteConnection
gremlin.remote.driver.clusterFile=conf/my-cluster.yaml
gremlin.remote.driver.sourceName=g
```

`my-cluster.yaml`File akan terlihat seperti ini:

```
hosts: [my-cluster-abcdefghijk.us-east-1.neptune.amazonaws.com]
port: 8182
serializer: { className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1,
              config: { serializeResultToString: false } }
connectionPool: { enableSsl: true }
```

**catatan**  
 Serializer dipindahkan dari `gremlin-driver` modul ke `gremlin-util` modul baru di versi 3.7.0. Paket diubah dari org.apache.tinkerpop.gremlin.driver.ser menjadi org.apache.tinkerpop.gremlin.util.ser. 

Mengkonfigurasi koneksi konsol Gremlin seperti itu memungkinkan Anda membuat jenis kueri berikut dengan sukses:

```
gremlin> 1+1
==>2

gremlin> x=g.V().count().next()
==>4249

gremlin> println("The answer was ${x}")
The answer was 4249
```

Anda dapat menghindari menampilkan hasilnya, seperti ini:

```
gremlin> x=g.V().count().next();[]
gremlin> println(x)
4249
```

Semua cara kueri yang biasa (tanpa langkah terminal) terus berfungsi. Contoh:

```
gremlin> g.V().count()
==>4249
```

Anda bahkan dapat menggunakan [https://tinkerpop.apache.org/docs/current/reference/#io-step](https://tinkerpop.apache.org/docs/current/reference/#io-step)langkah untuk memuat file dengan koneksi semacam ini.

## Autentikasi IAM
<a name="access-graph-gremlin-console-iam"></a>

Neptunus [mendukung otentikasi IAM](iam-auth-enable.md) untuk mengontrol akses ke cluster DB Anda. Jika autentikasi IAM diaktifkan, Anda harus menggunakan penandatanganan Signature Version 4 untuk mengautentikasi permintaan Anda. Untuk instruksi terperinci dan contoh kode untuk menghubungkan dari konsol Gremlin, lihat. [Menghubungkan ke database Amazon Neptunus menggunakan otentikasi IAM dengan konsol Gremlin](iam-auth-connecting-gremlin-console.md)

# Menggunakan titik akhir HTTPS REST untuk menyambung ke instans DB Neptune
<a name="access-graph-gremlin-rest"></a>

Amazon Neptune menyediakan titik akhir HTTPS untuk kueri Gremlin. Antarmuka REST kompatibel dengan apa pun versi Gremlin yang digunakan klaster DB Anda (lihat [halaman rilis mesin](engine-releases.md) dari versi mesin Neptune yang Anda jalankan untuk menentukan rilis Gremlin yang didukungnya).

**catatan**  
Sebagaimana dibahas dalam [Mengenkripsi koneksi ke database Amazon Neptunus Anda dengan SSL/HTTPS](security-ssl.md), Neptune sekarang mengharuskan Anda terhubung menggunakan HTTPS dan bukan HTTP. Selain itu, Neptunus saat ini tidak mendukung HTTP/2 untuk permintaan REST API. Klien harus menggunakan HTTP/1.1 saat menghubungkan ke titik akhir.

Petunjuk berikut memandu Anda menyambung ke titik akhir Gremlin menggunakan perintah `curl` dan HTTPS. Anda harus mengikuti petunjuk ini dari instans Amazon EC2 di virtual private cloud (VPC) yang sama seperti instans DB Neptune Anda.

Titik akhir HTTPS untuk kueri Gremlin ke instans DB Neptune adalah `https://your-neptune-endpoint:port/gremlin`.

**catatan**  
Untuk informasi tentang menemukan nama host instans DB Neptune Anda, lihat [Menghubungkan ke Titik Akhir Amazon Neptune.](feature-overview-endpoints.md).

## Untuk menyambung ke Neptune menggunakan titik akhir HTTP REST
<a name="access-graph-gremlin-rest-connect"></a>

Contoh berikut menggunakan **curl** untuk mengirimkan kueri Gremlin melalui **POST** HTTP. Kueri dikirimkan dalam format JSON dalam tubuh posting sebagai properti `gremlin`.

```
curl -X POST -d '{"gremlin":"g.V().limit(1)"}' https://your-neptune-endpoint:port/gremlin
```

Contoh ini mengembalikan vertex pertama dalam grafik menggunakan traversal `g.V().limit(1)`. Anda dapat mengajukan kueri untuk sesuatu yang lain dengan menggantinya dengan traversal Gremlin lain.

**penting**  
Secara default, titik akhir REST mengembalikan semua hasil dalam satu set hasil JSON. Jika set hasil ini terlalu besar, pengecualian `OutOfMemoryError` dapat terjadi pada instans DB Neptune.  
Anda dapat menghindari hal ini dengan mengaktifkan respons bongkahan (hasil dikembalikan dalam serangkaian respons terpisah). Lihat [Gunakan header jejak HTTP opsional untuk mengaktifkan respons multi-bagian Gremlin](access-graph-gremlin-rest-trailing-headers.md).

Meskipun permintaan **POST** HTTP direkomendasikan untuk mengirim kueri Gremlin, tetapi memungkinkan juga untuk menggunakan permintaan **GET** HTTP:

```
curl -G "https://your-neptune-endpoint:port?gremlin=g.V().count()"
```

**catatan**  
Neptune tidak mendukung properti `bindings`.

# Gunakan header jejak HTTP opsional untuk mengaktifkan respons multi-bagian Gremlin
<a name="access-graph-gremlin-rest-trailing-headers"></a>

Secara default, respons HTTP untuk kueri Gremlin dikembalikan dalam satu set hasil JSON. Dalam kasus set hasil yang sangat besar, ini dapat menyebabkan pengecualian `OutOfMemoryError` pada instans DB.

Namun, Anda dapat mengaktifkan respons *bongkahan* (respons yang dikembalikan dalam beberapa bagian yang terpisah). Anda melakukan ini dengan menyertakan header jejak transfer-encoding (TE) (`te: trailers`) dalam permintaan Anda. Lihat [halaman MDN tentang header permintaan TE](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/TE)) untuk informasi lebih lanjut tentang header TE.

Ketika respons dikembalikan dalam beberapa bagian, akan sulit untuk mendiagnosis masalah yang terjadi setelah bagian pertama diterima, karena bagian pertama tiba dengan kode status HTTP `200` (OK). Kegagalan berikutnya biasanya menghasilkan badan pesan yang berisi respons yang rusak, pada akhirnya Neptune menambahkan pesan kesalahan.

Agar deteksi dan diagnosis kegagalan semacam ini jadi lebih mudah, Neptune juga mencakup dua bidang header baru dalam trailing header dari setiap bongkahan respons:
+ `X-Neptune-Status`  –   berisi kode respons diikuti dengan nama pendek. Misalnya, dalam kasus keberhasilan, trailing header akan berupa: `X-Neptune-Status: 200 OK`. Dalam kasus kegagalan, kode respon akan menjadi salah satu [kode kesalahan mesin Neptune](errors-engine-codes.md), seperti `X-Neptune-Status: 500 TimeLimitExceededException`.
+ `X-Neptune-Detail`  –   kosong untuk permintaan yang berhasil. Dalam kasus kesalahan, ia berisi pesan kesalahan JSON. Karena hanya karakter ASCII yang diperbolehkan dalam nilai header HTTP, string JSON di-enkode dengan URL.

**catatan**  
Neptune saat ini tidak mendukung kompresi `gzip` respons bongkahan. Jika klien meminta kedua encoding bongkahan dan kompresi pada saat yang sama, Neptune melewatkan kompresi.

# Klien Gremlin berbasis Java untuk digunakan dengan Amazon Neptunus
<a name="access-graph-gremlin-client"></a>

[Anda dapat menggunakan salah satu dari dua klien Gremlin berbasis Java open-source dengan Amazon Neptunus: klien [Apache TinkerPop Java Gremlin, atau klien Gremlin](https://search.maven.org/artifact/org.apache.tinkerpop/gremlin-driver) untuk Amazon Neptunus.](https://search.maven.org/artifact/software.amazon.neptune/gremlin-client)

## Apache TinkerPop Java Gremlin klien
<a name="access-graph-gremlin-java-driver"></a>

Apache TinkerPop Java [gremlin-driver](https://tinkerpop.apache.org/docs/current/reference/#gremlin-java) adalah standar, klien Gremlin resmi yang bekerja dengan database grafik -enabled. TinkerPop Gunakan klien ini ketika Anda membutuhkan kompatibilitas maksimum dengan ruang TinkerPop pengembangan yang lebih luas, saat Anda bekerja dengan beberapa sistem database grafik, atau ketika Anda tidak memerlukan manajemen cluster lanjutan dan fitur load balancing khusus untuk Neptunus. Klien ini juga cocok untuk aplikasi sederhana yang terhubung ke satu instance Neptunus atau ketika Anda lebih suka menangani load balancing di tingkat infrastruktur daripada di dalam klien.

**penting**  
Memilih versi driver Apache TinkerPop Gremlin yang benar sangat penting untuk kompatibilitas dengan versi mesin Neptunus Anda. Menggunakan versi yang tidak kompatibel dapat mengakibatkan kegagalan koneksi atau perilaku yang tidak terduga. Untuk informasi kompatibilitas versi terperinci, lihat[Mengakses grafik Neptune dengan Gremlin](access-graph-gremlin.md).

**catatan**  
Tabel yang membantu Anda menentukan TinkerPop versi Apache yang benar untuk digunakan dengan Neptunus telah dipindahkan ke. [Mengakses grafik Neptune dengan Gremlin](access-graph-gremlin.md) Tabel ini sebelumnya terletak di halaman ini selama bertahun-tahun dan sekarang lebih terpusat untuk referensi untuk semua bahasa pemrograman yang TinkerPop mendukung.

## Klien Gremlin Java untuk Amazon Neptunus
<a name="access-graph-neptune-gremlin-client"></a>

Klien Gremlin untuk Amazon Neptunus adalah klien [Gremlin berbasis Java open-source yang bertindak sebagai pengganti drop-in](https://github.com/aws/neptune-gremlin-client) untuk klien Java standar. TinkerPop 

Klien Neptunus Gremlin dioptimalkan untuk cluster Neptunus. Ini memungkinkan Anda mengelola distribusi lalu lintas di beberapa instance dalam sebuah cluster, dan beradaptasi dengan perubahan topologi cluster saat Anda menambahkan atau menghapus replika. Anda bahkan dapat mengonfigurasi klien untuk mendistribusikan permintaan di seluruh subset instance di klaster Anda, berdasarkan peran, tipe instans, zona ketersediaan (AZ), atau tag yang terkait dengan instance.

[Versi terbaru dari klien Neptunus Gremlin Java tersedia di Maven](https://search.maven.org/artifact/software.amazon.neptune/gremlin-client) Central.

[Untuk informasi lebih lanjut tentang klien Neptunus Gremlin Java, lihat posting blog ini.](https://aws.amazon.com/blogs/database/load-balance-graph-queries-using-the-amazon-neptune-gremlin-client/) Untuk contoh kode dan demo, lihat [ GitHub proyek klien](https://github.com/aws/neptune-gremlin-client).

Saat memilih versi klien Neptunus Gremlin, Anda perlu mempertimbangkan versi yang TinkerPop mendasarinya sehubungan dengan versi mesin Neptunus Anda. Lihat tabel kompatibilitas di [Mengakses grafik Neptune dengan Gremlin](access-graph-gremlin.md) untuk menentukan TinkerPop versi yang benar untuk mesin Neptunus Anda, lalu gunakan tabel berikut untuk memilih versi klien Neptunus Gremlin yang sesuai:


**Kompatibilitas versi klien Neptunus Gremlin**  

| Versi klien Neptunus Gremlin | TinkerPop versi | 
| --- | --- | 
| 3.x | 3.7.x (AWS SDK for Java 2.x/1.x) | 
| 2.1.x | 3.7.x (AWS SDK for Java 1.x) | 
| 2.0.x | 3.6.x | 
| 1.12 | 3.5.x | 

# Menggunakan klien Java untuk terhubung ke instance DB Neptunus
<a name="access-graph-gremlin-java"></a>

Bagian berikut memandu Anda melalui menjalankan sampel Java lengkap yang terhubung ke instance DB Neptunus dan melakukan traversal Gremlin menggunakan klien Apache Gremlin. TinkerPop

Anda harus mengikuti petunjuk ini dari instans Amazon EC2 di virtual private cloud (VPC) yang sama seperti instans DB Neptune Anda.

**Untuk menyambung ke Neptune menggunakan Java**

1. Install Apache Maven pada instans EC2 Anda. Jika menggunakan Amazon Linux 2023 (lebih disukai), gunakan:

   ```
   sudo dnf update -y
   sudo dnf install maven -y
   ```

   Jika menggunakan Amazon Linux 2, unduh biner terbaru dari [https://maven.apache.org/download.cgi:](https://maven.apache.org/download.cgi:)

   ```
   sudo yum remove maven -y
   wget https://dlcdn.apache.org/maven/maven-3/ <version>/binaries/apache-maven-<version>-bin.tar.gz
   sudo tar -xzf apache-maven-<version>-bin.tar.gz -C /opt/
   sudo ln -sf /opt/apache-maven-<version> /opt/maven
   echo 'export MAVEN_HOME=/opt/maven' >> ~/.bashrc
   echo 'export PATH=$MAVEN_HOME/bin:$PATH' >> ~/.bashrc
   source ~/.bashrc
   ```

1. **Instal Java.** Perpustakaan Gremlin membutuhkan Java 8 atau 11. Anda dapat menginstal Java 11 sebagai berikut:
   + Jika Anda menggunakan [Amazon Linux 2 (AL2)](https://aws.amazon.com/amazon-linux-2):

     ```
     sudo amazon-linux-extras install java-openjdk11
     ```
   + Jika Anda menggunakan [Amazon Linux 2023 (AL2023)](https://docs.aws.amazon.com/linux/al2023/ug/what-is-amazon-linux.html):

     ```
     sudo yum install java-11-amazon-corretto-devel
     ```
   + Untuk distribusi lain, gunakan salah satu dari berikut ini yang sesuai:

     ```
     sudo yum install java-11-openjdk-devel
     ```

     atau:

     ```
     sudo apt-get install openjdk-11-jdk
     ```

1. **Setel Java 11 sebagai runtime default pada instans EC2 Anda:** Masukkan yang berikut ini untuk menetapkan Java 8 sebagai runtime default pada instans EC2 Anda:

   ```
   sudo /usr/sbin/alternatives --config java
   ```

   Saat diminta, masukkan nomor untuk Java 11.

1. **Buat direktori baru bernama`gremlinjava`:**

   ```
   mkdir gremlinjava
   cd gremlinjava
   ```

1.  Di direktori `gremlinjava`, buat file `pom.xml`, lalu buka file tersebut dalam editor teks:

   ```
   nano pom.xml
   ```

1. Salin JSON berikut ke dalam file `pom.xml` dan simpan filenya:

   ```
   <project xmlns="https://maven.apache.org/POM/4.0.0"
            xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
     <properties>
       <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     </properties>
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.amazonaws</groupId>
     <artifactId>GremlinExample</artifactId>
     <packaging>jar</packaging>
     <version>1.0-SNAPSHOT</version>
     <name>GremlinExample</name>
     <url>https://maven.apache.org</url>
     <dependencies>
       <dependency>
         <groupId>org.apache.tinkerpop</groupId>
         <artifactId>gremlin-driver</artifactId>
         <version>3.7.2</version>
       </dependency>
       <dependency>
         <groupId>org.slf4j</groupId>
         <artifactId>slf4j-jdk14</artifactId>
         <version>1.7.25</version>
       </dependency>
     </dependencies>
     <build>
       <plugins>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-compiler-plugin</artifactId>
           <version>2.5.1</version>
           <configuration>
             <source>11</source>
             <target>11</target>
           </configuration>
         </plugin>
           <plugin>
             <groupId>org.codehaus.mojo</groupId>
             <artifactId>exec-maven-plugin</artifactId>
             <version>1.3</version>
             <configuration>
               <executable>java</executable>
               <arguments>
                 <argument>-classpath</argument>
                 <classpath/>
                 <argument>com.amazonaws.App</argument>
               </arguments>
               <mainClass>com.amazonaws.App</mainClass>
               <complianceLevel>1.11</complianceLevel>
               <killAfter>-1</killAfter>
             </configuration>
           </plugin>
       </plugins>
     </build>
   </project>
   ```
**catatan**  
Jika Anda memodifikasi proyek Maven yang ada, dependensi yang diperlukan disorot dalam kode sebelumnya.

1. Buat subdirektori untuk kode sumber contoh (`src/main/java/com/amazonaws/`) dengan mengetik teks berikut pada baris perintah:

   ```
   mkdir -p src/main/java/com/amazonaws/
   ```

1. Di direktori `src/main/java/com/amazonaws/`, buat file bernama `App.java`, lalu buka file tersebut dalam editor teks.

   ```
   nano src/main/java/com/amazonaws/App.java
   ```

1. Salin hal berikut ke dalam file `App.java`. Ganti *your-neptune-endpoint* dengan alamat instans DB Neptunus Anda. *Jangan* sertakan prefiks `https://` di metode `addContactPoint`.
**catatan**  
Untuk informasi tentang menemukan nama host instans DB Neptune Anda, lihat [Menghubungkan ke Titik Akhir Amazon Neptune.](feature-overview-endpoints.md).

   ```
   package com.amazonaws;
   import org.apache.tinkerpop.gremlin.driver.Cluster;
   import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
   import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
   import static org.apache.tinkerpop.gremlin.process.traversal.AnonymousTraversalSource.traversal;
   import org.apache.tinkerpop.gremlin.driver.remote.DriverRemoteConnection;
   import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
   import org.apache.tinkerpop.gremlin.structure.T;
   
   public class App
   {
     public static void main( String[] args )
     {
       Cluster.Builder builder = Cluster.build();
       builder.addContactPoint("your-neptune-endpoint");
       builder.port(8182);
       builder.enableSsl(true);
   
       Cluster cluster = builder.create();
   
       GraphTraversalSource g = traversal().withRemote(DriverRemoteConnection.using(cluster));
   
       // Add a vertex.
       // Note that a Gremlin terminal step, e.g. iterate(), is required to make a request to the remote server.
       // The full list of Gremlin terminal steps is at https://tinkerpop.apache.org/docs/current/reference/#terminal-steps
       g.addV("Person").property("Name", "Justin").iterate();
   
       // Add a vertex with a user-supplied ID.
       g.addV("Custom Label").property(T.id, "CustomId1").property("name", "Custom id vertex 1").iterate();
       g.addV("Custom Label").property(T.id, "CustomId2").property("name", "Custom id vertex 2").iterate();
   
       g.addE("Edge Label").from(__.V("CustomId1")).to(__.V("CustomId2")).iterate();
   
       // This gets the vertices, only.
       GraphTraversal t = g.V().limit(3).elementMap();
   
       t.forEachRemaining(
         e ->  System.out.println(t.toList())
       );
   
       cluster.close();
     }
   }
   ```

   Untuk bantuan menghubungkan ke Neptunus SSL/TLS dengan (yang diperlukan), lihat. [Konfigurasi SSL/TLS](#access-graph-gremlin-java-ssl)

1. Kompilasikan dan jalankan sampel menggunakan perintah Maven berikut:

   ```
   mvn compile exec:exec
   ```

Contoh sebelumnya mengembalikan peta kunci dan nilai-nilai masing-masing properti untuk dua vertex pertama dalam grafik menggunakan traversal `g.V().limit(3).elementMap()`. Untuk mengajukan kueri untuk sesuatu yang lain, ganti dengan traversal Gremlin lain dengan salah satu metode ending yang tepat.

**catatan**  
Bagian akhir dari kueri Gremlin, `.toList()`, diperlukan untuk mengirimkan traversal ke server untuk evaluasi. Jika Anda tidak menyertakan metode tersebut atau metode setara lain, kueri tidak diserahkan ke instans DB Neptune.  
Anda juga harus menambahkan ending yang tepat ketika Anda menambahkan sebuah vertex atau edge, seperti ketika Anda menggunakan langkah `addV( )`.

Metode berikut mengirimkan kueri ke instans DB Neptune:
+ `toList()`
+ `toSet()`
+ `next()`
+ `nextTraverser()`
+ `iterate()`

## Konfigurasi SSL/TLS untuk klien Gremlin Java
<a name="access-graph-gremlin-java-ssl"></a>

Neptunus harus diaktifkan SSL/TLS secara default. Biasanya, jika driver Java dikonfigurasi dengan`enableSsl(true)`, ia dapat terhubung ke Neptunus tanpa harus mengatur `keyStore()` atau `trustStore()` dengan salinan lokal sertifikat.

Namun, jika instans yang Anda sambungkan tidak memiliki koneksi internet untuk memverifikasi sertifikat publik, atau jika sertifikat yang Anda gunakan tidak bersifat publik, Anda dapat mengambil langkah-langkah berikut untuk mengonfigurasi salinan sertifikat lokal:

**Menyiapkan salinan sertifikat lokal untuk mengaktifkan SSL/TLS**

1. Unduh dan instal [keytool](https://docs.oracle.com/javase/9/tools/keytool.htm#JSWOR-GUID-5990A2E4-78E3-47B7-AE75-6D1826259549) dari Oracle. Ini akan membuat pengaturan toko kunci lokal jauh lebih mudah.

1. Unduh sertifikat `SFSRootCAG2.pem` CA (Gremlin Java SDK memerlukan sertifikatuntuk memverifikasi sertifikat jarak jauh):

   ```
   wget https://www.amazontrust.com/repository/SFSRootCAG2.pem
   ```

1. Buat toko kunci dalam JKS atau PKCS12 format. Contoh ini menggunakan JKS. Jawab pertanyaan-pertanyaan yang mengikuti pada prompt. Kata sandi yang Anda buat di sini akan dibutuhkan nanti:

   ```
   keytool -genkey -alias (host name) -keyalg RSA -keystore server.jks
   ```

1. Impor `SFSRootCAG2.pem` file yang Anda unduh ke toko kunci yang baru dibuat:

   ```
   keytool -import -keystore server.jks -file .pem
   ```

1. Konfigurasikan `Cluster` objek secara terprogram:

   ```
   Cluster cluster = Cluster.build("(your neptune endpoint)")
                            .port(8182)
                            .enableSSL(true)
                            .keyStore(‘server.jks’)
                            .keyStorePassword("(the password from step 2)")
                            .create();
   ```

   Anda dapat melakukan hal yang sama dalam file konfigurasi jika Anda mau, seperti yang mungkin Anda lakukan dengan konsol Gremlin:

   ```
   hosts: [(your neptune endpoint)]
   port: 8182
   connectionPool: { enableSsl: true, keyStore: server.jks, keyStorePassword: (the password from step 2) }
   serializer: { className: org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1, config: { serializeResultToString: true }}
   ```

## Autentikasi IAM
<a name="access-graph-gremlin-java-iam"></a>

Neptunus [mendukung otentikasi IAM](iam-auth-enable.md) untuk mengontrol akses ke cluster DB Anda. Jika autentikasi IAM diaktifkan, Anda harus menggunakan penandatanganan Signature Version 4 untuk mengautentikasi permintaan Anda. Untuk petunjuk rinci dan contoh kode untuk menghubungkan dari klien Java, lihat[Menghubungkan ke database Amazon Neptunus menggunakan IAM dengan Gremlin Java](iam-auth-connecting-gremlin-java.md).

# Contoh Java tentang menghubungkan ke instans DB Neptune dengan logika sambungan ulang
<a name="access-graph-gremlin-java-reconnect-example"></a>

Contoh Java berikut menunjukkan cara terhubung ke klien Gremlin dengan logika sambungan ulang untuk pulih dari pemutusan sambungan tak terduga.

Contoh ini memiliki dependensi berikut:

```
<dependency>
    <groupId>org.apache.tinkerpop</groupId>
    <artifactId>gremlin-driver</artifactId>
    <version>${gremlin.version}</version>
</dependency>

<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>amazon-neptune-sigv4-signer</artifactId>
    <version>${sig4.signer.version}</version>
</dependency>

<dependency>
    <groupId>com.evanlennick</groupId>
    <artifactId>retry4j</artifactId>
    <version>0.15.0</version>
</dependency>
```

Berikut adalah kode sampelnya:

**penting**  
 `CallExecutor`Dari Retry4j mungkin tidak aman untuk utas. Pertimbangkan agar setiap utas menggunakan `CallExecutor` instancenya sendiri, atau gunakan pustaka percobaan ulang yang berbeda. 

**catatan**  
 Contoh berikut telah diperbarui untuk menyertakan penggunaan requestInterceptor (). Ini ditambahkan di TinkerPop 3.6.6. Sebelum TinkerPop versi 3.6.6, contoh kode menggunakan HandshakeInterceptor (), yang tidak digunakan lagi dengan rilis itu. 

```
public static void main(String args[]) {
  boolean useIam = true;

  // Create Gremlin cluster and traversal source
  Cluster.Builder builder = Cluster.build()
         .addContactPoint(System.getenv("neptuneEndpoint"))
         .port(Integer.parseInt(System.getenv("neptunePort")))
         .enableSsl(true)
         .minConnectionPoolSize(1)
         .maxConnectionPoolSize(1)
         .serializer(Serializers.GRAPHBINARY_V1D0)
         .reconnectInterval(2000);

  if (useIam) {
      builder.requestInterceptor( r -> {
         try {
            NeptuneNettyHttpSigV4Signer sigV4Signer =
                        new NeptuneNettyHttpSigV4Signer("(your region)", new DefaultAWSCredentialsProviderChain());
            sigV4Signer.signRequest(r);
         } catch (NeptuneSigV4SignerException e) {
            throw new RuntimeException("Exception occurred while signing the request", e);
         }
         return r;
      });
   }

  Cluster cluster = builder.create();

  GraphTraversalSource g = AnonymousTraversalSource
      .traversal()
      .withRemote(DriverRemoteConnection.using(cluster));

  // Configure retries
  RetryConfig retryConfig = new RetryConfigBuilder()
      .retryOnCustomExceptionLogic(getRetryLogic())
      .withDelayBetweenTries(1000, ChronoUnit.MILLIS)
      .withMaxNumberOfTries(5)
      .withFixedBackoff()
      .build();

  @SuppressWarnings("unchecked")
  CallExecutor<Object> retryExecutor = new CallExecutorBuilder<Object>()
      .config(retryConfig)
      .build();

  // Do lots of queries
  for (int i = 0; i < 100; i++){
    String id = String.valueOf(i);

    @SuppressWarnings("unchecked")
    Callable<Object> query = () -> g.V(id)
        .fold()
        .coalesce(
            unfold(),
            addV("Person").property(T.id, id))
        .id().next();

    // Retry query
    // If there are connection failures, the Java Gremlin client will automatically
    // attempt to reconnect in the background, so all we have to do is wait and retry.
    Status<Object> status = retryExecutor.execute(query);

    System.out.println(status.getResult().toString());
  }

  cluster.close();
}

private static Function<Exception, Boolean> getRetryLogic() {

  return e -> {

    Class<? extends Exception> exceptionClass = e.getClass();

    StringWriter stringWriter = new StringWriter();
    String message = stringWriter.toString();


    if (RemoteConnectionException.class.isAssignableFrom(exceptionClass)){
      System.out.println("Retrying because RemoteConnectionException");
      return true;
    }

    // Check for connection issues
    if (message.contains("Timed out while waiting for an available host") ||
        message.contains("Timed-out") && message.contains("waiting for connection on Host") ||
        message.contains("Connection to server is no longer active") ||
        message.contains("Connection reset by peer") ||
        message.contains("SSLEngine closed already") ||
        message.contains("Pool is shutdown") ||
        message.contains("ExtendedClosedChannelException") ||
        message.contains("Broken pipe") ||
        message.contains(System.getenv("neptuneEndpoint")))
    {
      System.out.println("Retrying because connection issue");
      return true;
    };

    // Concurrent writes can sometimes trigger a ConcurrentModificationException.
    // In these circumstances you may want to backoff and retry.
    if (message.contains("ConcurrentModificationException")) {
      System.out.println("Retrying because ConcurrentModificationException");
      return true;
    }

    // If the primary fails over to a new instance, existing connections to the old primary will
    // throw a ReadOnlyViolationException. You may want to back and retry.
    if (message.contains("ReadOnlyViolationException")) {
      System.out.println("Retrying because ReadOnlyViolationException");
      return true;
    }

    System.out.println("Not a retriable error");
    return false;
  };
}
```

# Menggunakan Python untuk terhubung ke instans DB Neptune
<a name="access-graph-gremlin-python"></a>

**penting**  
Memilih versi driver Apache TinkerPop Gremlin yang benar sangat penting untuk kompatibilitas dengan versi mesin Neptunus Anda. Menggunakan versi yang tidak kompatibel dapat mengakibatkan kegagalan koneksi atau perilaku yang tidak terduga. Untuk informasi kompatibilitas versi terperinci, lihat[Mengakses grafik Neptune dengan Gremlin](access-graph-gremlin.md).

Bagian berikut memandu Anda melalui proses berjalannya sampel Python yang menyambungkan ke instans Amazon Neptune DB dan melakukan traversal Gremlin.

Anda harus mengikuti petunjuk ini dari instans Amazon EC2 di virtual private cloud (VPC) yang sama seperti instans DB Neptune Anda.

Sebelum memulai, lakukan hal berikut:
+ Unduh dan pasang Python 3.6 atau yang lebih baru dari [Situs web Python.org](https://www.python.org/downloads/).
+ Pastikan Anda memiliki **pip** diinstal. Jika Anda tidak punya **pip** atau Anda tidak yakin, lihat [Apakah saya perlu menginstal pip?](https://pip.pypa.io/en/stable/installing/#do-i-need-to-install-pip) di dokumentasi **pip**.
+ Jika instalasi Python Anda belum memilikinya, unduh `futures` seperti berikut: `pip install futures`



**Untuk menyambung ke Neptune menggunakan Python**

1. Masukkan hal berikut untuk menginstal paket `gremlinpython`:

   ```
   pip install --user gremlinpython
   ```

1. Buat file bernama `gremlinexample.py`, lalu buka file tersebut dalam editor teks.

1. Salin hal berikut ke dalam file `gremlinexample.py`. Ganti *your-neptune-endpoint* dengan alamat cluster DB Neptunus Anda *your-neptune-port* dan dengan port cluster DB Neptunus Anda (default:8182). 

   Untuk informasi tentang menemukan alamat instans DB Neptune Anda, lihat bagian [Menghubungkan ke Titik Akhir Amazon Neptune.](feature-overview-endpoints.md).

    Contoh di bawah ini menunjukkan bagaimana untuk terhubung dengan Gremlin Python. 

   ```
   import boto3
   import os
   from botocore.auth import SigV4Auth
   from botocore.awsrequest import AWSRequest
   from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
   from gremlin_python.process.anonymous_traversal import traversal
   
   database_url = "wss://your-neptune-endpoint:your-neptune-port/gremlin"
   
   remoteConn = DriverRemoteConnection(database_url, "g")
   
   g = traversal().withRemote(remoteConn)
   
   print(g.inject(1).toList())
   remoteConn.close()
   ```

1. Masukkan perintah berikut untuk menjalankan sampel:

   ```
   python gremlinexample.py
   ```

   Kueri Gremlin pada akhir contoh ini mengembalikan vertex (`g.V().limit(2)`) dalam daftar. Daftar ini kemudian dicetak dengan fungsi `print` standar Python.
**catatan**  
Bagian akhir dari kueri Gremlin, `toList()`, diperlukan untuk mengirimkan traversal ke server untuk evaluasi. Jika Anda tidak menyertakan metode tersebut atau metode setara lain, kueri tidak diserahkan ke instans DB Neptune.

   Metode berikut mengirimkan kueri ke instans DB Neptune:
   + `toList()`
   + `toSet()`
   + `next()`
   + `nextTraverser()`
   + `iterate()`

   

   Contoh sebelumnya mengembalikan dua vertex pertama dalam grafik menggunakan traversal `g.V().limit(2).toList()`. Untuk mengajukan kueri untuk sesuatu yang lain, ganti dengan traversal Gremlin lain dengan salah satu metode ending yang tepat.

## Autentikasi IAM
<a name="access-graph-gremlin-python-iam"></a>

Neptunus [mendukung otentikasi IAM](iam-auth-enable.md) untuk mengontrol akses ke cluster DB Anda. Jika autentikasi IAM diaktifkan, Anda harus menggunakan penandatanganan Signature Version 4 untuk mengautentikasi permintaan Anda. Untuk petunjuk rinci dan contoh kode untuk menghubungkan dari klien Python, lihat. [Menghubungkan ke database Amazon Neptunus menggunakan otentikasi IAM dengan Python Gremlin](gremlin-python-iam-auth.md)

# Gunakan .NET untuk terhubung ke instans DB Neptune
<a name="access-graph-gremlin-dotnet"></a>

**penting**  
Memilih versi driver Apache TinkerPop Gremlin yang benar sangat penting untuk kompatibilitas dengan versi mesin Neptunus Anda. Menggunakan versi yang tidak kompatibel dapat mengakibatkan kegagalan koneksi atau perilaku yang tidak terduga. Untuk informasi kompatibilitas versi terperinci, lihat[Mengakses grafik Neptune dengan Gremlin](access-graph-gremlin.md).

Bagian berikut berisi contoh kode yang ditulis dalam C\$1 yang menyambung ke instans DB Neptune dan melakukan traversal Gremlin.

Sambungan ke Amazon Neptune harus berasal dari Instans Amazon EC2 di virtual private cloud (VPC) yang sama seperti instans DB Neptune Anda. Kode sampel ini diuji pada instans Amazon EC2 yang menjalankan Ubuntu.

Sebelum memulai, lakukan hal berikut:
+ Instal .NET pada instans Amazon EC2. Untuk mendapatkan petunjuk cara menginstal .NET di beberapa sistem operasi, termasuk Windows, Linux, dan macOS, lihat [Memulai dengan .NET](https://www.microsoft.com/net/learn/get-started/).
+ Instal Gremlin.NET dengan menjalankan `dotnet add package gremlin.net` untuk paket Anda. Untuk informasi selengkapnya, lihat [Gremlin.net di dokumentasi](https://tinkerpop.apache.org/docs/current/reference/#gremlin-DotNet). TinkerPop 



**Untuk menyambung ke Neptune menggunakan Gremlin.NET**

1. Buat proyek .NET baru.

   ```
   dotnet new console -o gremlinExample
   ```

1. Ubah direktori ke direktori proyek baru.

   ```
   cd gremlinExample
   ```

1. Salin hal berikut ke dalam file `Program.cs`. Ganti *your-neptune-endpoint* dengan alamat instans DB Neptunus Anda.

   Untuk informasi tentang menemukan alamat instans DB Neptune Anda, lihat bagian [Menghubungkan ke Titik Akhir Amazon Neptune.](feature-overview-endpoints.md).

   ```
   using System;
   using System.Threading.Tasks;
   using System.Collections.Generic;
   using Gremlin.Net;
   using Gremlin.Net.Driver;
   using Gremlin.Net.Driver.Remote;
   using Gremlin.Net.Structure;
   using static Gremlin.Net.Process.Traversal.AnonymousTraversalSource;
   namespace gremlinExample
   {
     class Program
     {
       static void Main(string[] args)
       {
         try
         {
           var endpoint = "your-neptune-endpoint";
           // This uses the default Neptune and Gremlin port, 8182
           var gremlinServer = new GremlinServer(endpoint, 8182, enableSsl: true );
           var gremlinClient = new GremlinClient(gremlinServer);
           var remoteConnection = new DriverRemoteConnection(gremlinClient, "g");
           var g = Traversal().WithRemote(remoteConnection);
           g.AddV("Person").Property("Name", "Justin").Iterate();
           g.AddV("Custom Label").Property("name", "Custom id vertex 1").Iterate();
           g.AddV("Custom Label").Property("name", "Custom id vertex 2").Iterate();
           var output = g.V().Limit<Vertex>(3).ToList();
           foreach(var item in output) {
               Console.WriteLine(item);
           }
         }
         catch (Exception e)
         {
             Console.WriteLine("{0}", e);
         }
       }
     }
   }
   ```

1. Masukkan perintah berikut untuk menjalankan sampel:

   ```
   dotnet run
   ```

   Kueri Gremlin pada akhir contoh ini mengembalikan jumlah vertex tunggal untuk tujuan pengujian. Ini kemudian dicetak ke konsol.
**catatan**  
Bagian akhir dari kueri Gremlin, `Next()`, diperlukan untuk mengirimkan traversal ke server untuk evaluasi. Jika Anda tidak menyertakan metode tersebut atau metode setara lain, kueri tidak diserahkan ke instans DB Neptune.

   Metode berikut mengirimkan kueri ke instans DB Neptune:
   + `ToList()`
   + `ToSet()`
   + `Next()`
   + `NextTraverser()`
   + `Iterate()`

   Gunakan `Next()` jika Anda membutuhkan hasil kueri agar diserialkan dan dikembalikan, atau `Iterate()` jika tidak.

   Contoh sebelumnya mengembalikan daftar dengan menggunakan traversal. `g.V().Limit(3).ToList()` Untuk mengajukan kueri untuk sesuatu yang lain, ganti dengan traversal Gremlin lain dengan salah satu metode ending yang tepat.

## Autentikasi IAM
<a name="access-graph-gremlin-dotnet-iam"></a>

Neptunus [mendukung otentikasi IAM](iam-auth-enable.md) untuk mengontrol akses ke cluster DB Anda. Jika autentikasi IAM diaktifkan, Anda harus menggunakan penandatanganan Signature Version 4 untuk mengautentikasi permintaan Anda. Untuk petunjuk rinci dan contoh kode untuk menghubungkan dari klien.NET, lihat[Menghubungkan ke database Amazon Neptunus menggunakan otentikasi IAM dengan Gremlin.NET](gremlin-dotnet-iam-auth.md).

# Gunakan Node.js untuk terhubung ke instans DB Neptune
<a name="access-graph-gremlin-node-js"></a>

**penting**  
Memilih versi driver Apache TinkerPop Gremlin yang benar sangat penting untuk kompatibilitas dengan versi mesin Neptunus Anda. Menggunakan versi yang tidak kompatibel dapat mengakibatkan kegagalan koneksi atau perilaku yang tidak terduga. Untuk informasi kompatibilitas versi terperinci, lihat[Mengakses grafik Neptune dengan Gremlin](access-graph-gremlin.md).

Bagian berikut memandu Anda melalui proses berjalannya sampel Node.js yang menyambungkan ke instans Amazon Neptune DB dan melakukan traversal Gremlin.

Anda harus mengikuti petunjuk ini dari instans Amazon EC2 di virtual private cloud (VPC) yang sama seperti instans DB Neptune Anda.

Sebelum memulai, lakukan hal berikut:
+ Pastikan Node.js versi 8.11 atau lebih tinggi yang diinstal. Jika bukan, unduh dan instal Node.js dari [Situs web Nodejs.org](https://nodejs.org).

**Untuk menyambung ke Neptune menggunakan Node.js**

1. Masukkan hal berikut untuk menginstal paket `gremlin-javascript`:

   ```
   npm install gremlin
   ```

1. Buat file bernama `gremlinexample.js`, lalu buka file tersebut dalam editor teks.

1. Salin hal berikut ke dalam file `gremlinexample.js`. Ganti *your-neptune-endpoint* dengan alamat instans DB Neptunus Anda.

   Untuk informasi tentang menemukan alamat instans DB Neptune Anda, lihat bagian [Menghubungkan ke Titik Akhir Amazon Neptune.](feature-overview-endpoints.md).

   ```
   const gremlin = require('gremlin');
   const DriverRemoteConnection = gremlin.driver.DriverRemoteConnection;
   const Graph = gremlin.structure.Graph;
   
   dc = new DriverRemoteConnection('wss://your-neptune-endpoint:8182/gremlin',{});
   
   const graph = new Graph();
   const g = graph.traversal().withRemote(dc);
   
   g.V().limit(1).count().next().
       then(data => {
           console.log(data);
           dc.close();
       }).catch(error => {
           console.log('ERROR', error);
           dc.close();
       });
   ```

1. Masukkan perintah berikut untuk menjalankan sampel:

   ```
   node gremlinexample.js
   ```

Contoh sebelumnya mengembalikan jumlah vertex tunggal dalam grafik menggunakan traversal `g.V().limit(1).count().next()`. Untuk mengajukan kueri untuk sesuatu yang lain, ganti dengan traversal Gremlin lain dengan salah satu metode ending yang tepat.

**catatan**  
Bagian akhir dari kueri Gremlin, `next()`, diperlukan untuk mengirimkan traversal ke server untuk evaluasi. Jika Anda tidak menyertakan metode tersebut atau metode setara lain, kueri tidak diserahkan ke instans DB Neptune.

Metode berikut mengirimkan kueri ke instans DB Neptune:
+ `toList()`
+ `toSet()`
+ `next()`
+ `nextTraverser()`
+ `iterate()`

Gunakan `next()` jika Anda membutuhkan hasil kueri agar diserialkan dan dikembalikan, atau `iterate()` jika tidak.

**penting**  
Ini adalah contoh Node.js mandiri. Jika Anda berencana untuk menjalankan kode seperti ini dalam suatu AWS Lambda fungsi, lihat [Contoh fungsi Lambda](lambda-functions-examples.md) detail tentang penggunaan JavaScript secara efisien dalam fungsi Lambda Neptunus.

## Autentikasi IAM
<a name="access-graph-gremlin-nodejs-iam"></a>

Neptunus [mendukung otentikasi IAM](iam-auth-enable.md) untuk mengontrol akses ke cluster DB Anda. Jika autentikasi IAM diaktifkan, Anda harus menggunakan penandatanganan Signature Version 4 untuk mengautentikasi permintaan Anda. Untuk instruksi terperinci dan contoh kode untuk menghubungkan dari JavaScript klien, lihat[Menghubungkan ke database Amazon Neptunus menggunakan otentikasi IAM dengan Gremlin JavaScript](gremlin-javascript-iam-auth.md).

# Menggunakan Go untuk terhubung ke instans DB Neptunus
<a name="access-graph-gremlin-go"></a>

**penting**  
Memilih versi driver Apache TinkerPop Gremlin yang benar sangat penting untuk kompatibilitas dengan versi mesin Neptunus Anda. Menggunakan versi yang tidak kompatibel dapat mengakibatkan kegagalan koneksi atau perilaku yang tidak terduga. Untuk informasi kompatibilitas versi terperinci, lihat[Mengakses grafik Neptune dengan Gremlin](access-graph-gremlin.md).

**catatan**  
Versi 3.5.x gremlingo kompatibel dengan versi 3.4.x selama Anda hanya menggunakan TinkerPop fitur 3.4.x dalam kueri Gremlin yang Anda tulis.

Bagian berikut memandu Anda melalui menjalankan sampel Go yang terhubung ke instans Amazon Neptunus DB dan melakukan traversal Gremlin.

Anda harus mengikuti petunjuk ini dari instans Amazon EC2 di virtual private cloud (VPC) yang sama seperti instans DB Neptune Anda.

Sebelum memulai, lakukan hal berikut:
+ Unduh dan instal Go 1.17 atau yang lebih baru dari situs web [go.dev.](https://go.dev/dl/)

**Untuk terhubung ke Neptunus menggunakan Go**

1. Mulai dari direktori kosong, inisialisasi modul Go baru:

   ```
   go mod init example.com/gremlinExample
   ```

1. Tambahkan gremlin-go sebagai dependensi modul baru Anda:

   ```
   go get github.com/apache/tinkerpop/gremlin-go/v3/driver
   ```

1. Buat file bernama `gremlinExample.go` dan kemudian buka di editor teks.

1. Salin yang berikut ini ke dalam `gremlinExample.go` file, ganti *`(your neptune endpoint)`* dengan alamat instans DB Neptunus Anda:

   ```
   package main
   
   import (
     "fmt"
     gremlingo "github.com/apache/tinkerpop/gremlin-go/v3/driver"
   )
   
   func main() {
     // Creating the connection to the server.
     driverRemoteConnection, err := gremlingo.NewDriverRemoteConnection("wss://(your neptune endpoint):8182/gremlin",
       func(settings *gremlingo.DriverRemoteConnectionSettings) {
         settings.TraversalSource = "g"
       })
     if err != nil {
       fmt.Println(err)
       return
     }
     // Cleanup
     defer driverRemoteConnection.Close()
   
     // Creating graph traversal
     g := gremlingo.Traversal_().WithRemote(driverRemoteConnection)
   
     // Perform traversal
     results, err := g.V().Limit(2).ToList()
     if err != nil {
       fmt.Println(err)
       return
     }
     // Print results
     for _, r := range results {
       fmt.Println(r.GetString())
     }
   }
   ```
**catatan**  
Format sertifikat Neptunus TLS saat ini tidak didukung di Go 1.18\$1 dengan macOS, dan mungkin memberikan kesalahan 509 saat mencoba memulai koneksi. Untuk pengujian lokal, ini dapat dilewati dengan menambahkan “crypto/tls” ke impor dan memodifikasi pengaturan sebagai berikut: `DriverRemoteConnection`  

   ```
   // Creating the connection to the server.
   driverRemoteConnection, err := gremlingo.NewDriverRemoteConnection("wss://your-neptune-endpoint:8182/gremlin",
     func(settings *gremlingo.DriverRemoteConnectionSettings) {
         settings.TraversalSource = "g"
         settings.TlsConfig = &tls.Config{InsecureSkipVerify: true}
     })
   ```

1. Masukkan perintah berikut untuk menjalankan sampel:

   ```
   go run gremlinExample.go
   ```

Query Gremlin di akhir contoh ini mengembalikan simpul `(g.V().Limit(2))` dalam irisan. Irisan ini kemudian diulang dan dicetak dengan `fmt.Println` fungsi standar.

**catatan**  
Bagian akhir dari kueri Gremlin, `ToList()`, diperlukan untuk mengirimkan traversal ke server untuk evaluasi. Jika Anda tidak menyertakan metode tersebut atau metode setara lain, kueri tidak diserahkan ke instans DB Neptune.

Metode berikut mengirimkan kueri ke instans DB Neptune:
+ `ToList()`
+ `ToSet()`
+ `Next()`
+ `GetResultSet()`
+ `Iterate()`

Contoh sebelumnya mengembalikan dua vertex pertama dalam grafik menggunakan traversal `g.V().Limit(2).ToList()`. Untuk mengajukan kueri untuk sesuatu yang lain, ganti dengan traversal Gremlin lain dengan salah satu metode ending yang tepat.

## Autentikasi IAM
<a name="access-graph-gremlin-go-iam"></a>

Neptunus [mendukung otentikasi IAM](iam-auth-enable.md) untuk mengontrol akses ke cluster DB Anda. Jika autentikasi IAM diaktifkan, Anda harus menggunakan penandatanganan Signature Version 4 untuk mengautentikasi permintaan Anda. Untuk petunjuk rinci dan contoh kode untuk menghubungkan dari klien Go, lihat[Menghubungkan ke database Amazon Neptunus menggunakan otentikasi IAM dengan Gremlin Go](gremlin-go-iam-auth.md).

# Menggunakan AWS SDK untuk menjalankan kueri Gremlin
<a name="access-graph-gremlin-sdk"></a>

Dengan AWS SDK, Anda dapat menjalankan kueri Gremlin terhadap grafik Neptunus Anda menggunakan bahasa pemrograman pilihan Anda. Neptunus data API SDK (`neptunedata`nama layanan) menyediakan tindakan untuk mengirimkan kueri [ExecuteGremlinQuery](https://docs.aws.amazon.com/neptune/latest/data-api/API_ExecuteGremlinQuery.html)Gremlin.

Anda harus menjalankan contoh ini dari instans Amazon EC2 di virtual private cloud (VPC) yang sama dengan cluster DB Neptunus Anda, atau dari lokasi yang memiliki konektivitas jaringan ke titik akhir cluster Anda.

Tautan langsung ke dokumentasi referensi API untuk `neptunedata` layanan di setiap bahasa SDK dapat ditemukan di bawah ini:


| Bahasa pemrograman | referensi API neptunedata | 
| --- | --- | 
| C\$1\$1 | [https://sdk.amazonaws.com/cpp/api/LATEST/aws-cpp-sdk-neptunedata/html/annotated.html](https://sdk.amazonaws.com/cpp/api/LATEST/aws-cpp-sdk-neptunedata/html/annotated.html) | 
| Go | [https://docs.aws.amazon.com/sdk-for-go/api/service/neptunedata/](https://docs.aws.amazon.com/sdk-for-go/api/service/neptunedata/) | 
| Java | [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/neptunedata/package-summary.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/neptunedata/package-summary.html) | 
| JavaScript | [https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-client-neptunedata/](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/Package/-aws-sdk-client-neptunedata/) | 
| Kotlin | [https://sdk.amazonaws.com/kotlin/api/latest/neptunedata/index.html](https://sdk.amazonaws.com/kotlin/api/latest/neptunedata/index.html) | 
| .NET | [https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Neptunedata/NNeptunedata.html](https://docs.aws.amazon.com/sdkfornet/v3/apidocs/items/Neptunedata/NNeptunedata.html) | 
| PHP | [https://docs.aws.amazon.com/aws-sdk-php/v3/api/namespace-Aws.Neptunedata.html](https://docs.aws.amazon.com/aws-sdk-php/v3/api/namespace-Aws.Neptunedata.html) | 
| Python | [https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/neptunedata.html](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/neptunedata.html) | 
| Ruby | [https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/Neptunedata.html](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/Neptunedata.html) | 
| Karat | [https://crates.io/crates/aws-sdk-neptunedata](https://crates.io/crates/aws-sdk-neptunedata) | 
| CLI | [https://docs.aws.amazon.com/cli/latest/reference/neptunedata/](https://docs.aws.amazon.com/cli/latest/reference/neptunedata/) | 

## Contoh SDK Gremlin AWS
<a name="access-graph-gremlin-sdk-examples"></a>

Contoh berikut menunjukkan cara menyiapkan `neptunedata` klien, menjalankan kueri Gremlin, dan mencetak hasilnya. Ganti *YOUR\$1NEPTUNE\$1HOST* dan *YOUR\$1NEPTUNE\$1PORT* dengan titik akhir dan port cluster DB Neptunus Anda.

**Konfigurasi batas waktu sisi klien dan coba lagi**  
Batas waktu klien SDK mengontrol berapa lama *klien* menunggu respons. Itu tidak mengontrol berapa lama kueri berjalan di server. Jika waktu klien habis sebelum server selesai, kueri dapat terus berjalan di Neptunus sementara klien tidak memiliki cara untuk mengambil hasilnya.  
Sebaiknya atur batas waktu baca sisi klien ke `0` (tanpa batas waktu) atau ke nilai yang setidaknya beberapa detik lebih lama dari pengaturan neptune\$1query\$1timeout sisi server di cluster DB [Neptunus](parameters.md#parameters-db-cluster-parameters-neptune_query_timeout) Anda. Ini memungkinkan Neptunus mengontrol saat waktu kueri habis.  
Kami juga merekomendasikan pengaturan upaya coba ulang maksimum ke `1` (tidak ada percobaan ulang). Jika SDK mencoba ulang kueri yang masih berjalan di server, itu dapat menghasilkan operasi duplikat. Ini sangat penting untuk kueri mutasi, di mana percobaan lagi dapat menyebabkan duplikat penulisan yang tidak diinginkan.

------
#### [ Python ]

1. 4. Ikuti [instruksi instalasi](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html) untuk menginstal Boto3.

1. Buat file bernama `gremlinExample.py` dan tempel kode berikut:

   ```
   import boto3
   import json
   from botocore.config import Config
   
   # Disable the client-side read timeout and retries so that
   # Neptune's server-side neptune_query_timeout controls query duration.
   client = boto3.client(
       'neptunedata',
       endpoint_url=f'https://YOUR_NEPTUNE_HOST:YOUR_NEPTUNE_PORT',
       config=Config(read_timeout=None, retries={'total_max_attempts': 1})
   )
   
   # Use the untyped GraphSON v3 serializer for a cleaner JSON response.
   response = client.execute_gremlin_query(
       gremlinQuery='g.V().limit(1)',
       serializer='application/vnd.gremlin-v3.0+json;types=false'
   )
   
   print(json.dumps(response['result'], indent=2))
   ```

1. Jalankan contoh: `python gremlinExample.py`

------
#### [ Java ]

1. Ikuti [petunjuk penginstalan](https://docs.aws.amazon.com//sdk-for-java/latest/developer-guide/setup.html) untuk menyiapkan AWS SDK for Java.

1. Gunakan kode berikut untuk menyiapkan`NeptunedataClient`, menjalankan kueri Gremlin, dan mencetak hasilnya:

   ```
   import java.net.URI;
   import java.time.Duration;
   import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
   import software.amazon.awssdk.core.retry.RetryPolicy;
   import software.amazon.awssdk.services.neptunedata.NeptunedataClient;
   import software.amazon.awssdk.services.neptunedata.model.ExecuteGremlinQueryRequest;
   import software.amazon.awssdk.services.neptunedata.model.ExecuteGremlinQueryResponse;
   
   // Disable the client-side timeout and retries so that
   // Neptune's server-side neptune_query_timeout controls query duration.
   NeptunedataClient client = NeptunedataClient.builder()
       .endpointOverride(URI.create("https://YOUR_NEPTUNE_HOST:YOUR_NEPTUNE_PORT"))
       .overrideConfiguration(ClientOverrideConfiguration.builder()
           .apiCallTimeout(Duration.ZERO)
           .retryPolicy(RetryPolicy.none())
           .build())
       .build();
   
   // Use the untyped GraphSON v3 serializer for a cleaner JSON response.
   ExecuteGremlinQueryRequest request = ExecuteGremlinQueryRequest.builder()
       .gremlinQuery("g.V().limit(1)")
       .serializer("application/vnd.gremlin-v3.0+json;types=false")
       .build();
   
   ExecuteGremlinQueryResponse response = client.executeGremlinQuery(request);
   
   System.out.println(response.result().toString());
   ```

------
#### [ JavaScript ]

1. Ikuti [petunjuk penginstalan](https://docs.aws.amazon.com//sdk-for-javascript/v3/developer-guide/getting-started-nodejs.html) untuk menyiapkan AWS SDK. JavaScript Instal paket klien neptunedata:. `npm install @aws-sdk/client-neptunedata`

1. Buat file bernama `gremlinExample.js` dan tempel kode berikut:

   ```
   import { NeptunedataClient, ExecuteGremlinQueryCommand } from "@aws-sdk/client-neptunedata";
   import { NodeHttpHandler } from "@smithy/node-http-handler";
   
   const config = {
       endpoint: "https://YOUR_NEPTUNE_HOST:YOUR_NEPTUNE_PORT",
       // Disable the client-side request timeout so that
       // Neptune's server-side neptune_query_timeout controls query duration.
       requestHandler: new NodeHttpHandler({
           requestTimeout: 0
       }),
       maxAttempts: 1
   };
   
   const client = new NeptunedataClient(config);
   
   // Use the untyped GraphSON v3 serializer for a cleaner JSON response.
   const input = {
       gremlinQuery: "g.V().limit(1)",
       serializer: "application/vnd.gremlin-v3.0+json;types=false"
   };
   
   const command = new ExecuteGremlinQueryCommand(input);
   const response = await client.send(command);
   
   console.log(JSON.stringify(response, null, 2));
   ```

1. Jalankan contoh: `node gremlinExample.js`

------

# Petunjuk kueri Gremlin
<a name="gremlin-query-hints"></a>

Gunakan petunjuk kueri untuk menentukan optimasi dan evaluasi strategi untuk kueri Gremlin tertentu di Amazon Neptune. 

Petunjuk kueri ditentukan dengan menambahkan langkah `withSideEffect` untuk kueri dengan sintaks berikut.

```
g.withSideEffect(hint, value)
```
+ *petunjuk* – Mengidentifikasi jenis petunjuk yang akan diterapkan.
+ *nilai* – Menentukan perilaku aspek sistem yang sedang dipertimbangkan.

Sebagai contoh, hal berikut ini menunjukkan bagaimana cara memasukkan petunjuk `repeatMode`dalam traversal Gremlin.

**catatan**  
Semua efek samping petunjuk kueri Gremlin diprefiks dengan `Neptune#`.

```
g.withSideEffect('Neptune#repeatMode', 'DFS').V("3").repeat(out()).times(10).limit(1).path()
```

Kueri sebelumnya menginstruksikan mesin Neptune untuk melakukan traversal pada grafik *Depth First* (`DFS`) ketimbang Neptune default, *Breadth First* (`BFS`).

Bagian berikut menyediakan informasi selengkapnya tentang petunjuk kueri yang tersedia dan penggunaannya.

**Topics**
+ [

# Petunjuk kueri repeatMode Gremlin
](gremlin-query-hints-repeatMode.md)
+ [

# Petunjuk kueri noReordering Gremlin
](gremlin-query-hints-noReordering.md)
+ [

# Petunjuk permintaan TypePromotion Gremlin
](gremlin-query-hints-typePromotion.md)
+ [

# Petunjuk kueri useDFE Gremlin
](gremlin-query-hints-useDFE.md)
+ [

# Petunjuk kueri Gremlin untuk menggunakan cache hasil
](gremlin-query-hints-results-cache.md)

# Petunjuk kueri repeatMode Gremlin
<a name="gremlin-query-hints-repeatMode"></a>

Petunjuk kueri `repeatMode` Neptune menentukan bagaimana mesin Neptune mengevaluasi langkah `repeat()` dalam traversal Gremlin: breadth first, depth first, atau chunked depth first.

Mode evaluasi langkah `repeat()` penting ketika digunakan untuk menemukan atau mengikuti jalur, bukan hanya mengulangi langkah dalam jumlah pengulangan terbatas.

## Sintaksis
<a name="gremlin-query-hints-repeatMode-syntax"></a>

Petunjuk kueri `repeatMode` ditentukan dengan menambahkan langkah `withSideEffect` untuk kueri.

```
g.withSideEffect('Neptune#repeatMode', 'mode').gremlin-traversal
```

**catatan**  
Semua efek samping petunjuk kueri Gremlin diprefiks dengan `Neptune#`.

**Mode yang Tersedia**
+ `BFS`

  Pencarian Breadth-First

  Mode eksekusi default untuk langkah `repeat()`. Ini mendapat semua node saudara sebelum pergi lebih dalam sepanjang jalur.

  Versi ini intensif memori dan perbatasan bisa menjadi sangat besar. Ada risiko yang lebih tinggi bahwa kueri akan kehabisan memori dan dibatalkan oleh mesin Neptune. Ini paling cocok dengan implementasi Gremlin lainnya.
+ `DFS`

  Pencarian Depth-First

  Mengikuti setiap jalur ke kedalaman maksimum sebelum beralih ke solusi berikutnya.

  Ini menggunakan lebih sedikit memori. Ini dapat memberikan performa yang lebih baik dalam situasi seperti menemukan jalur tunggal dari titik awal ke beberapa hop.
+ `CHUNKED_DFS`

  Pencarian Chunked Depth-First

  Pendekatan hibrida yang mengeksplorasi depth-first grafik dalam potongan 1.000 node, bukan 1 node (`DFS`) atau semua node (`BFS)`).

  Mesin Neptune akan mendapatkan hingga 1.000 node pada setiap tingkat sebelum mengikuti jalur yang lebih dalam.

  Ini adalah pendekatan yang seimbang antara kecepatan dan penggunaan memori. 

  Hal ini juga berguna jika Anda ingin menggunakan `BFS`, tapi kueri menggunakan terlalu banyak memori.



## Contoh
<a name="gremlin-query-hints-repeatMode-example"></a>

Bagian berikut menjelaskan efek dari mode pengulangan pada traversal Gremlin.

Di Neptune, mode default untuk langkah `repeat()` adalah untuk melakukan strategi eksekusi breadth-first (`BFS`) untuk semua traversal. 

Dalam kebanyakan kasus, TinkerGraph implementasi menggunakan strategi eksekusi yang sama, tetapi dalam beberapa kasus mengubah eksekusi traversal. 

Misalnya, TinkerGraph implementasi memodifikasi query berikut.

```
g.V("3").repeat(out()).times(10).limit(1).path()
```

Langkah `repeat()` dalam traversal ini di-“unrolled” ke dalam traversal berikut, yang menghasilkan strategi depth-first (`DFS`).

```
g.V(<id>).out().out().out().out().out().out().out().out().out().out().limit(1).path()
```

**penting**  
Mesin permintaan Neptune tidak melakukan ini secara otomatis.

Breadth-first (`BFS`) adalah strategi eksekusi default, dan mirip dengan TinkerGraph dalam kebanyakan kasus. Namun, ada kasus-kasus tertentu di mana strategi depth (`DFS`) lebih baik.

 

**BFS (Default)**  
Breadth-first (BFS) adalah strategi eksekusi default untuk operator `repeat()`.

```
g.V("3").repeat(out()).times(10).limit(1).path()
```

Mesin Neptune sepenuhnya mengeksplorasi perbatasan sembilan hop pertama sebelum menemukan sepuluh hop solusi. Hal ini efektif dalam banyak kasus, seperti kueri jalur terpendek.

Namun, untuk contoh sebelumnya, traversal akan jauh lebih cepat menggunakan mode depth-first (`DFS`) untuk operator `repeat()`.

**DFS**  
Kueri berikut menggunakan mode depth-first (`DFS`) untuk operator `repeat()`.

```
g.withSideEffect("Neptune#repeatMode", "DFS").V("3").repeat(out()).times(10).limit(1)
```

Ini mengikuti setiap solusi individu ke kedalaman maksimum sebelum menjelajahi solusi berikutnya. 

# Petunjuk kueri noReordering Gremlin
<a name="gremlin-query-hints-noReordering"></a>

Ketika Anda mengirimkan traversal Gremlin, mesin kueri Neptune menyelidiki struktur traversal dan mengurutkan ulang bagian dari kueri, mencoba untuk meminimalkan jumlah pekerjaan yang diperlukan untuk evaluasi dan waktu respons kueri. Sebagai contoh, sebuah traversal dengan beberapa kendala, seperti beberapa langkah `has()`, biasanya tidak dievaluasi dalam urutan yang diberikan. Sebaliknya traversal diurutkan ulang setelah kueri diperiksa dengan analisis statis.

Mesin kueri Neptune mencoba untuk mengidentifikasi kendala mana yang lebih selektif dan menjalankannya terlebih dulu. Hal ini sering menghasilkan performa yang lebih baik, tetapi urutan yang dipilih Neptune untuk mengevaluasi kueri mungkin tidak selalu optimal.

Jika Anda tahu karakteristik data yang tepat dan ingin secara manual mendikte urutan eksekusi kueri, Anda dapat menggunakan petunjuk kueri `noReordering` Neptune untuk menentukan bahwa traversal dievaluasi dalam urutan yang diberikan.

## Sintaksis
<a name="gremlin-query-hints-noReordering-syntax"></a>

Petunjuk kueri `noReordering` ditentukan dengan menambahkan langkah `withSideEffect` untuk kueri.

```
g.withSideEffect('Neptune#noReordering', true or false).gremlin-traversal
```

**catatan**  
Semua efek samping petunjuk kueri Gremlin diprefiks dengan `Neptune#`.

**Nilai yang Tersedia**
+ `true`
+ `false`

# Petunjuk permintaan TypePromotion Gremlin
<a name="gremlin-query-hints-typePromotion"></a>

Ketika Anda mengirimkan traversal Gremlin yang memfilter di atas nilai atau jangkauan numerik, mesin kueri Neptune biasanya harus menggunakan promosi jenis ketika mengeksekusi kueri. Ini berarti bahwa mesin harus memeriksa nilai-nilai dari setiap jenis yang dapat memegang nilai yang Anda gunakan untuk menyaring.

Misalnya, jika Anda menyaring untuk nilai yang sama dengan 55, mesin harus mencari bilangan bulat yang sama dengan 55, bilangan bulat panjang sama dengan 55L, mengapung sama dengan 55.0, dan sebagainya. Setiap promosi jenis memerlukan pencarian tambahan pada penyimpanan, yang dapat menyebabkan permintaan yang tampaknya sederhana tiba-tiba mengambil waktu yang lama untuk menyelesaikan.

Katakanlah Anda sedang mencari semua vertex dengan properti customer-age lebih besar dari 5:

```
g.V().has('customerAge', gt(5))
```

Untuk mengeksekusi traversal yang secara menyeluruh, Neptune harus memperluas kueri untuk memeriksa setiap jenis numerik yang dapat mempromosikan nilai Anda kueri. Dalam hal ini, filter `gt` harus diterapkan untuk setiap integer lebih dari 5, setiap panjang lebih dari 5L, setiap float lebih dari 5.0, dan setiap ganda lebih 5.0. Karena masing-masing promosi jenis ini memerlukan pencarian tambahan pada penyimpanan, Anda akan melihat beberapa filter per filter numerik ketika Anda menjalankan [API `profile` Gremlin](gremlin-profile-api.md) untuk kueri ini, dan akan memakan waktu lebih lama untuk menyelesaikan dari yang mungkin Anda harapkan.

Sering kali promosi jenis tidak perlu karena Anda tahu sebelumnya bahwa Anda hanya perlu menemukan nilai dari satu jenis tertentu. Ketika hal ini terjadi, Anda dapat mempercepat kueri Anda secara dramatis dengan menggunakan petunjuk kueri `typePromotion` untuk mematikan promosi jenis.

## Sintaksis
<a name="gremlin-query-hints-typePromotion-syntax"></a>

Petunjuk kueri `typePromotion` ditentukan dengan menambahkan langkah `withSideEffect` untuk kueri.

```
g.withSideEffect('Neptune#typePromotion', true or false).gremlin-traversal
```

**catatan**  
Semua efek samping petunjuk kueri Gremlin diprefiks dengan `Neptune#`.

**Nilai yang Tersedia**
+ `true`
+ `false`

Untuk menonaktifkan promosi jenis untuk kueri di atas, Anda akan menggunakan:

```
g.withSideEffect('Neptune#typePromotion', false).V().has('customerAge', gt(5))
```

# Petunjuk kueri useDFE Gremlin
<a name="gremlin-query-hints-useDFE"></a>

Gunakan petunjuk kueri ini untuk mengaktifkan penggunaan DFE untuk mengeksekusi kueri. [Secara default Neptunus tidak menggunakan DFE tanpa petunjuk kueri ini disetel ke, karena parameter instance neptune\$1dfe\$1query\$1engine default `true` ke.](parameters.md#parameters-instance-parameters-neptune_dfe_query_engine) `viaQueryHint` Jika Anda menyetel parameter instance itu`enabled`, mesin DFE digunakan untuk semua kueri kecuali yang memiliki petunjuk `useDFE` kueri yang disetel ke. `false`

Contoh mengaktifkan DFE untuk kueri:

```
g.withSideEffect('Neptune#useDFE', true).V().out()
```

# Petunjuk kueri Gremlin untuk menggunakan cache hasil
<a name="gremlin-query-hints-results-cache"></a>

Petunjuk kueri berikut dapat digunakan saat [cache hasil kueri](gremlin-results-cache.md) diaktifkan.

## Petunjuk kueri Gremlin `enableResultCache`
<a name="gremlin-query-hints-results-cache-enableResultCache"></a>

Petunjuk `enableResultCache` kueri dengan nilai `true` menyebabkan hasil kueri dikembalikan dari cache jika sudah di-cache. Jika tidak, ia mengembalikan hasil baru dan men-cache mereka sampai waktu mereka dihapus dari cache. Contoh:

```
g.with('Neptune#enableResultCache', true)
 .V().has('genre','drama').in('likes')
```

Kemudian, Anda dapat mengakses hasil cache dengan mengeluarkan kueri yang persis sama lagi.

Jika nilai petunjuk kueri ini`false`, atau jika tidak ada, hasil kueri tidak di-cache. Namun, menyetelnya ke `false` tidak menghapus hasil cache yang ada. Untuk menghapus hasil cache, gunakan `invalidateResultCachekey` petunjuk `invalidateResultCache` atau.

## Petunjuk kueri Gremlin `enableResultCacheWithTTL`
<a name="gremlin-query-hints-results-cache-enableResultCacheWithTTL"></a>

Petunjuk `enableResultCacheWithTTL` kueri juga mengembalikan hasil cache jika ada, tanpa mempengaruhi TTL hasil yang sudah ada di cache. Jika saat ini tidak ada hasil cache, kueri mengembalikan hasil baru dan menyimpannya dalam cache untuk waktu hidup (TTL) yang ditentukan oleh petunjuk `enableResultCacheWithTTL` kueri. Waktu untuk hidup ditentukan dalam hitungan detik. Misalnya, kueri berikut menentukan waktu untuk hidup enam puluh detik:

```
g.with('Neptune#enableResultCacheWithTTL', 60)
 .V().has('genre','drama').in('likes')
```

Sebelum 60 detik time-to-live selesai, Anda dapat menggunakan kueri yang sama (di sini,`g.V().has('genre','drama').in('likes')`) dengan petunjuk `enableResultCache` atau `enableResultCacheWithTTL` kueri untuk mengakses hasil yang di-cache.

**catatan**  
Waktu untuk hidup ditentukan dengan `enableResultCacheWithTTL` tidak mempengaruhi hasil yang telah di-cache.  
Jika hasil sebelumnya di-cache menggunakan`enableResultCache`, cache harus terlebih dahulu dihapus secara eksplisit sebelum `enableResultCacheWithTTL` menghasilkan hasil baru dan menyimpannya untuk TTL yang ditentukannya.
Jika hasil sebelumnya di-cache menggunakan`enableResultCachewithTTL`, TTL sebelumnya harus kedaluwarsa terlebih dahulu sebelum `enableResultCacheWithTTL` menghasilkan hasil baru dan menyimpannya untuk TTL yang ditentukannya.

Setelah waktu untuk hidup berlalu, hasil cache untuk kueri dihapus, dan contoh berikutnya dari kueri yang sama kemudian mengembalikan hasil baru. Jika `enableResultCacheWithTTL` dilampirkan ke kueri berikutnya, hasil baru di-cache dengan TTL yang ditentukannya.

## Petunjuk kueri Gremlin `invalidateResultCacheKey`
<a name="gremlin-query-hints-results-cache-invalidateResultCacheKey"></a>

Petunjuk `invalidateResultCacheKey` kueri dapat mengambil `false` nilai `true` atau. `true`Nilai menyebabkan hasil cache untuk kueri yang `invalidateResultCacheKey` dilampirkan akan dihapus. Misalnya, contoh berikut menyebabkan hasil cache `g.V().has('genre','drama').in('likes')` untuk kunci kueri dihapus:

```
g.with('Neptune#invalidateResultCacheKey', true)
 .V().has('genre','drama').in('likes')
```

Contoh kueri di atas tidak menyebabkan hasil barunya di-cache. Anda dapat menyertakan `enableResultCache` (atau`enableResultCacheWithTTL`) dalam kueri yang sama jika Anda ingin menyimpan hasil baru setelah menghapus hasil cache yang ada:

```
g.with('Neptune#enableResultCache', true)
 .with('Neptune#invalidateResultCacheKey', true)
 .V().has('genre','drama').in('likes')
```

## Petunjuk kueri Gremlin `invalidateResultCache`
<a name="gremlin-query-hints-results-cache-invalidateResultCache"></a>

Petunjuk `invalidateResultCache` kueri dapat mengambil `false` nilai `true` atau. `true`Nilai menyebabkan semua hasil dalam cache hasil dihapus. Contoh:

```
g.with('Neptune#invalidateResultCache', true)
 .V().has('genre','drama').in('likes')
```

Contoh query di atas tidak menyebabkan hasilnya di-cache. Anda dapat menyertakan `enableResultCache` (atau`enableResultCacheWithTTL`) dalam kueri yang sama jika Anda ingin menyimpan hasil baru setelah benar-benar menghapus cache yang ada:

```
g.with('Neptune#enableResultCache', true)
 .with('Neptune#invalidateResultCache', true)
 .V().has('genre','drama').in('likes')
```

## Petunjuk kueri Gremlin `numResultsCached`
<a name="gremlin-query-hints-results-cache-numResultsCached"></a>

Petunjuk `numResultsCached` kueri hanya dapat digunakan dengan kueri yang berisi`iterate()`, dan menentukan jumlah maksimum hasil untuk cache untuk kueri yang dilampirkan. Perhatikan bahwa hasil yang di-cache saat `numResultsCached` ada tidak dikembalikan, hanya di-cache.

Misalnya, kueri berikut menetapkan bahwa hingga 100 hasilnya harus di-cache, tetapi tidak ada hasil cache yang dikembalikan:

```
g.with('Neptune#enableResultCache', true)
 .with('Neptune#numResultsCached', 100)
 .V().has('genre','drama').in('likes').iterate()
```

Anda kemudian dapat menggunakan kueri seperti berikut ini untuk mengambil rentang hasil cache (di sini, sepuluh pertama):

```
g.with('Neptune#enableResultCache', true)
 .with('Neptune#numResultsCached', 100)
 .V().has('genre','drama').in('likes').range(0, 10)
```

## Petunjuk kueri Gremlin `noCacheExceptions`
<a name="gremlin-query-hints-results-cache-noCacheExceptions"></a>

Petunjuk `noCacheExceptions` kueri dapat mengambil `false` nilai `true` atau. `true`Nilai menyebabkan pengecualian apa pun yang terkait dengan cache hasil ditekan. Contoh:

```
g.with('Neptune#enableResultCache', true)
 .with('Neptune#noCacheExceptions', true)
 .V().has('genre','drama').in('likes')
```

Secara khusus, ini menekan`QueryLimitExceededException`, yang dinaikkan jika hasil kueri terlalu besar untuk dimasukkan ke dalam cache hasil.

# API status kueri Gremlin
<a name="gremlin-api-status"></a>

Untuk mendapatkan status kueri Gremlin, gunakan HTTP `GET` atau `POST` untuk membuat permintaan ke titik akhir `https://your-neptune-endpoint:port/gremlin/status`. 

## Parameter permintaan status kueri Gremlin
<a name="gremlin-api-status-get-request"></a>
+ **queryId** (*opsional*) - ID dari kueri Gremlin yang berjalan. Hanya menampilkan status kueri yang ditentukan.
+ **includeWaiting** (*opsional*) - Mengembalikan status semua kueri yang menunggu.

  Biasanya, hanya menjalankan kueri yang disertakan dalam respons, tetapi ketika parameter `includeWaiting` ditentukan, status semua kueri yang menunggu juga dikembalikan.

## Sintaks respons status kueri Gremlin
<a name="gremlin-api-status-get-response-syntax"></a>

```
{
  "acceptedQueryCount": integer,
  "runningQueryCount": integer,
  "queries": [
    {
      "queryId":"guid",
      "queryEvalStats":
        {
          "waited": integer,
          "elapsed": integer,
          "cancelled": boolean
        },
      "queryString": "string"
    }
  ]
}
```

## Nilai respons status kueri Gremlin
<a name="gremlin-api-status-get-response-values"></a>
+ **acceptedQueryCount**— Jumlah kueri yang telah diterima tetapi belum selesai, termasuk kueri dalam antrian.
+ **runningQueryCount**— Jumlah kueri Gremlin yang sedang berjalan.
+ **queries** — Daftar kueri Gremlin saat ini.
+ **queryId** — id GUID untuk kueri. Neptune secara otomatis memberikan nilai ID ini ke setiap kueri, atau Anda juga dapat menetapkan ID Anda sendiri (lihat [Menyuntikkan ID Kustom Ke Dalam Gremlin Neptune atau Kueri SPARQL](features-query-id.md)).
+ **queryEvalStats**— Statistik untuk kueri ini.
+ **subqueries** — Jumlah subqueries dalam kueri ini.
+ **elapsed** — Jumlah milidetik kueri telah berjalan sejauh ini.
+ **cancelled** — True menunjukkan bahwa kueri dibatalkan.
+ **queryString** — Query yang dikirimkan. Ini dipotong menjadi 1024 karakter jika lebih panjang dari itu.
+ **menunggu** - Menunjukkan berapa lama kueri menunggu, dalam milidetik.

## Contoh status kueri Gremlin
<a name="gremlin-api-status-get-example"></a>

Berikut ini adalah contoh perintah status menggunakan `curl` dan `GET` HTTP.

```
curl https://your-neptune-endpoint:port/gremlin/status
```

Output ini menunjukkan satu kueri yang berjalan.

```
{
  "acceptedQueryCount":9,
  "runningQueryCount":1,
  "queries": [
    {
      "queryId":"fb34cd3e-f37c-4d12-9cf2-03bb741bf54f",
      "queryEvalStats":
        {
          "waited": 0,
          "elapsed": 23,
          "cancelled": false
        },
      "queryString": "g.V().out().count()"
    }
  ]
}
```

# Pembatalan kueri Gremlin
<a name="gremlin-api-status-cancel"></a>

Untuk mendapatkan status kueri Gremlin, gunakan HTTP `GET` atau `POST` untuk membuat permintaan ke titik akhir `https://your-neptune-endpoint:port/gremlin/status`.

## Parameter permintaan pembatalan kueri Gremlin
<a name="gremlin-api-status-cancel-request"></a>
+ **cancelQuery** — Diperlukan untuk pembatalan. Parameter ini tidak memiliki nilai yang sesuai.
+ **queryId** — ID dari kueri Gremlin yang sedang berjalan untuk dibatalkan.

## Contoh pembatalan kueri Gremlin
<a name="gremlin-api-status-cancel-example"></a>

Berikut ini adalah contoh perintah `curl` untuk membatalkan kueri.

```
curl https://your-neptune-endpoint:port/gremlin/status \
  --data-urlencode "cancelQuery" \
  --data-urlencode "queryId=fb34cd3e-f37c-4d12-9cf2-03bb741bf54f"
```

Keberhasilan pembatalan kembali HTTP `200` OK.

# Support untuk sesi berbasis skrip Gremlin
<a name="access-graph-gremlin-sessions"></a>

Anda dapat menggunakan sesi Gremlin dengan transaksi implisit di Amazon Neptune. Untuk informasi tentang sesi Gremlin, lihat [Mempertimbangkan Sesi](http://tinkerpop.apache.org/docs/current/reference/#sessions) dalam dokumentasi TinkerPop Apache. Bagian di bawah ini menjelaskan cara menggunakan sesi Gremlin dengan Java.

**penting**  
Saat ini, waktu terlama Neptunus dapat menjaga sesi berbasis skrip terbuka adalah 10 menit. Jika Anda tidak menutup sesi sebelum itu, waktu sesi habis dan semua yang ada di dalamnya di-rollback.

**Topics**
+ [

## Sesi Gremlin pada konsol Gremlin
](#access-graph-gremlin-sessions-console)
+ [

## Sesi Gremlin dalam Varian Bahasa Gremlin
](#access-graph-gremlin-sessions-glv)

## Sesi Gremlin pada konsol Gremlin
<a name="access-graph-gremlin-sessions-console"></a>

Jika Anda membuat koneksi jauh pada Konsol Gremlin tanpa parameter `session`, koneksi jauh dibuat di mode *sessionless*. Dalam mode ini, setiap permintaan yang diserahkan ke server diperlakukan sebagai transaksi lengkap dalam permintaan itu sendiri, dan tidak ada status yang disimpan antara permintaan. Jika permintaan gagal, hanya permintaan tersebut yang di-rollback.

Jika Anda membuat koneksi jarak jauh *yang* menggunakan `session` parameter, Anda membuat sesi berbasis skrip yang berlangsung hingga Anda menutup koneksi jarak jauh. Setiap sesi diidentifikasi oleh UUID unik yang dihasilkan konsol dan dikembalikan kepada Anda.

Berikut ini adalah contoh satu panggilan konsol yang menciptakan sesi. Setelah kueri dikirimkan, panggilan lain menutup sesi dan melakukan kueri.

**catatan**  
Klien Gremlin harus selalu ditutup untuk melepaskan sumber daya sisi server.

```
gremlin> :remote connect tinkerpop.server conf/neptune-remote.yaml session
  . . .
  . . .
gremlin> :remote close
```

Untuk informasi dan contoh selengkapnya, lihat [Sesi](http://tinkerpop.apache.org/docs/current/reference/#console-sessions) dalam TinkerPop dokumentasi.

Semua pertanyaan yang Anda jalankan selama sesi membentuk satu transaksi yang tidak dilakukan sampai semua permintaan berhasil dan Anda menutup sambungan jarak jauh. Jika kueri gagal, atau jika Anda tidak menutup koneksi dalam masa sesi maksimum yang Neptune dukung, transaksi sesi tidak dilakukan, dan semua kueri di dalamnya di-rollback.

## Sesi Gremlin dalam Varian Bahasa Gremlin
<a name="access-graph-gremlin-sessions-glv"></a>

Dalam varian bahasa Gremlin (GLV), Anda perlu membuat objek `SessionedClient` untuk mengeluarkan beberapa kueri dalam satu transaksi, seperti dalam contoh berikut.

```
try {                              // line 1
  Cluster cluster = Cluster.open();                    // line 2
  Client client = cluster.connect("sessionName");      // line 3
   ...
   ...
} finally {
  // Always close. If there are no errors, the transaction is committed; otherwise, it's rolled back.
  client.close();
}
```

Baris 3 pada contoh sebelumnya membuat `SessionedClient` objek sesuai dengan opsi konfigurasi yang ditetapkan untuk cluster yang dimaksud. *sessionName*String yang Anda berikan ke metode connect menjadi nama unik sesi. Untuk menghindari tabrakan, gunakan UUID untuk nama tersebut.

Klien mulai transaksi sesi ketika diinisialisasi. Semua kueri yang Anda jalankan selama bentuk sesi dilakukan hanya ketika Anda memanggil `client.close( )`. Sekali lagi, jika kueri gagal, atau jika Anda tidak menutup koneksi dalam masa sesi maksimum yang Neptune dukung, transaksi sesi gagal, dan semua kueri di dalamnya di-rollback.

**catatan**  
Klien Gremlin harus selalu ditutup untuk melepaskan sumber daya sisi server.

```
GraphTraversalSource g = traversal().withRemote(conn);

Transaction tx = g.tx();

// Spawn a GraphTraversalSource from the Transaction.
// Traversals spawned from gtx are executed within a single transaction.
GraphTraversalSource gtx = tx.begin();
try {
  gtx.addV('person').iterate();
  gtx.addV('software').iterate();

  tx.commit();
} finally {
    if (tx.isOpen()) {
        tx.rollback();
    }
}
```

# Transaksi Gremlin di Neptunus
<a name="access-graph-gremlin-transactions"></a>

[Ada beberapa konteks di mana transaksi Gremlin dijalankan.](transactions.md) Saat bekerja dengan Gremlin, penting untuk memahami konteks tempat Anda bekerja dan apa implikasinya:
+ **`Script-based`**— Permintaan dibuat menggunakan string Gremlin berbasis teks, seperti ini:
  + Menggunakan driver Java dan `Client.submit(string)`
  + Menggunakan konsol Gremlin dan. `:remote connect`
  + Menggunakan HTTP API.
+ **`Bytecode-based`**— Permintaan dibuat menggunakan bytecode Gremlin serial khas Gremlin Language Variants ([GLV](https://tinkerpop.apache.org/docs/current/reference/#gremlin-drivers-variants)).

  Misalnya, menggunakan driver Java,`g = traversal().withRemote(...)`.

Untuk salah satu konteks di atas, ada konteks tambahan dari permintaan yang dikirim sebagai tanpa sesi atau terikat pada sesi.

**catatan**  
 Transaksi Gremlin harus selalu dilakukan atau dibatalkan, sehingga sumber daya sisi server dapat dilepaskan. Jika terjadi kesalahan selama transaksi, penting untuk mencoba kembali seluruh transaksi dan bukan hanya permintaan tertentu yang gagal. 

## Permintaan tanpa sesi
<a name="access-graph-gremlin-transactions-sessionless"></a>

 Ketika sessionless, permintaan setara dengan satu transaksi.

Untuk skrip, implikasinya adalah bahwa satu atau lebih pernyataan Gremlin yang dikirim dalam satu permintaan akan melakukan atau mengembalikan sebagai satu transaksi. Contoh:

```
Cluster cluster = Cluster.open();
Client client = cluster.connect(); // sessionless
// 3 vertex additions in one request/transaction:
client.submit("g.addV();g.addV();g.addV()").all().get();
```

Untuk bytecode, permintaan tanpa sesi dibuat untuk setiap traversal yang muncul dan dieksekusi dari: `g`

```
GraphTraversalSource g = traversal().withRemote(...);

// 3 vertex additions in three individual requests/transactions:
g.addV().iterate();
g.addV().iterate();
g.addV().iterate();

// 3 vertex additions in one single request/transaction:
g.addV().addV().addV().iterate();
```

## Permintaan terikat pada sesi
<a name="access-graph-gremlin-transactions-session-bound"></a>

Ketika terikat ke sesi, beberapa permintaan dapat diterapkan dalam konteks satu transaksi.

Untuk skrip, implikasinya adalah bahwa tidak perlu menggabungkan semua operasi grafik menjadi satu nilai string yang disematkan:

```
Cluster cluster = Cluster.open();
Client client = cluster.connect(sessionName); // session
try {
    // 3 vertex additions in one request/transaction:
    client.submit("g.addV();g.addV();g.addV()").all().get();
} finally {
    client.close();
}

try {
    // 3 vertex additions in three requests, but one transaction:
    client.submit("g.addV()").all().get(); // starts a new transaction with the same sessionName
    client.submit("g.addV()").all().get();
    client.submit("g.addV()").all().get();
} finally {
    client.close();
}
```

Untuk bytecode, setelah TinkerPop `3.5.x`, transaksi dapat dikontrol secara eksplisit dan sesi dikelola secara transparan. Gremlin Language Variants (GLV) mendukung `tx()` sintaks Gremlin atau transaksi sebagai berikut: `commit()` `rollback()`

```
GraphTraversalSource g = traversal().withRemote(conn);

Transaction tx = g.tx();

// Spawn a GraphTraversalSource from the Transaction.
// Traversals spawned from gtx are executed within a single transaction.
GraphTraversalSource gtx = tx.begin();
try {
    gtx.addV('person').iterate();
    gtx.addV('software').iterate();

    tx.commit();
} finally {
    if (tx.isOpen()) {
        tx.rollback();
    }
}
```

Meskipun contoh di atas ditulis dalam Java, Anda juga dapat menggunakan `tx()` sintaks ini dalam Python, Javascript dan .NET.

**Awas**  
[Kueri hanya-baca tanpa sesi dijalankan di bawah isolasi [SNAPSHOT](transactions-isolation-levels.md), tetapi kueri hanya-baca yang dijalankan dalam transaksi eksplisit dijalankan di bawah isolasi SERIALIZABLE.](transactions-isolation-levels.md) Kueri hanya-baca yang dijalankan di bawah `SERIALIZABLE` isolasi menimbulkan overhead yang lebih tinggi dan dapat memblokir atau diblokir oleh penulisan bersamaan, tidak seperti yang dijalankan di bawah isolasi. `SNAPSHOT`

# Menggunakan API Gremlin dengan Amazon Neptune
<a name="gremlin-api-reference"></a>

**catatan**  
Amazon Neptune tidak mendukung properti `bindings`.

Permintaan Gremlin HTTPS semua menggunakan titik akhir tunggal: `https://your-neptune-endpoint:port/gremlin`. Semua koneksi Neptune harus menggunakan HTTPS.

Anda dapat menghubungkan Konsol Gremlin ke grafik Neptunus secara langsung. WebSockets

Untuk informasi selengkapnya tentang menghubungkan ke titik akhir Gremlin, lihat [Mengakses grafik Neptune dengan Gremlin](access-graph-gremlin.md).

Implementasi Amazon Neptune untuk Gremlin memiliki detail dan perbedaan spesifik yang perlu Anda pertimbangkan. Untuk informasi selengkapnya, lihat [Kepatuhan standar Gremlin di Amazon Neptune](access-graph-gremlin-differences.md).

Untuk informasi tentang bahasa Gremlin dan traversal, lihat [The Traversal](https://tinkerpop.apache.org/docs/current/reference/#traversal) dalam dokumentasi Apache. TinkerPop 

# Hasil kueri cache di Amazon Neptunus Gremlin
<a name="gremlin-results-cache"></a>

Amazon Neptunus mendukung cache hasil untuk kueri Gremlin.

Anda dapat mengaktifkan cache hasil kueri dan kemudian menggunakan petunjuk kueri untuk menyimpan hasil kueri hanya-baca Gremlin.

Setiap menjalankan ulang kueri kemudian mengambil hasil yang di-cache dengan latensi rendah dan tanpa I/O biaya, selama masih dalam cache. Ini berfungsi untuk kueri yang dikirimkan baik pada titik akhir HTTP dan menggunakan Websockets, baik sebagai kode byte atau dalam bentuk string.

**catatan**  
Kueri yang dikirim ke titik akhir profil tidak di-cache bahkan ketika cache kueri diaktifkan.

Anda dapat mengontrol bagaimana cache hasil kueri Neptunus berperilaku dalam beberapa cara. Contoh:
+ Anda bisa mendapatkan hasil cache paginasi, dalam blok.
+ Anda dapat menentukan time-to-live (TTL) untuk kueri tertentu.
+ Anda dapat menghapus cache untuk kueri tertentu.
+ Anda dapat menghapus seluruh cache.
+ Anda dapat mengatur untuk diberi tahu jika hasil melebihi ukuran cache.

Cache dipertahankan menggunakan kebijakan least-recently-used (LRU), yang berarti bahwa setelah ruang yang dialokasikan ke cache penuh, least-recently-used hasilnya dihapus untuk memberi ruang ketika hasil baru di-cache.

**penting**  
Cache hasil kueri tidak tersedia pada `t3.medium` atau jenis `t4.medium` instance.

## Mengaktifkan cache hasil kueri di Neptunus
<a name="gremlin-results-cache-enabling"></a>

 Cache hasil kueri dapat diaktifkan di semua instance dalam cluster atau per-instance. Untuk mengaktifkan cache hasil pada semua instance dalam sebuah cluster, atur `neptune_result_cache` parameter di cluster `cluster-parameter-group` ke`1`. Untuk mengaktifkan ini pada instance tertentu, atur `neptune_result_cache` parameter dalam instance `instance-parameter-group` ke`1`. Pengaturan grup parameter cluster akan mengganti nilai grup parameter instance. 

 Restart diperlukan pada setiap instance yang terpengaruh untuk pengaturan parameter cache hasil yang akan diterapkan. Meskipun Anda dapat mengaktifkan cache hasil di semua instance dalam cluster melalui`cluster-parameter-group`, setiap instance mempertahankan cache-nya sendiri. Fitur cache hasil kueri bukan cache di seluruh cluster. 

Setelah cache hasil diaktifkan, Neptunus menyisihkan sebagian memori saat ini untuk hasil kueri caching. Semakin besar jenis instans yang Anda gunakan dan semakin banyak memori yang tersedia, semakin banyak memori yang disisihkan Neptunus untuk cache.

Jika memori cache hasil terisi, Neptunus secara otomatis least-recently-used menjatuhkan (LRU) hasil cache untuk memberi jalan bagi yang baru.

Anda dapat memeriksa status cache hasil saat ini menggunakan [Status instans](access-graph-status.md) perintah.

## Menggunakan petunjuk untuk menyimpan hasil kueri cache
<a name="gremlin-results-cache-using"></a>

Setelah cache hasil kueri diaktifkan, Anda menggunakan petunjuk kueri untuk mengontrol cache kueri. Semua contoh di bawah ini berlaku untuk traversal kueri yang sama, yaitu:

```
g.V().has('genre','drama').in('likes')
```

### Menggunakan `enableResultCache`
<a name="using-enableResultCache"></a>

Dengan cache hasil kueri diaktifkan, Anda dapat menyimpan hasil kueri Gremlin menggunakan petunjuk `enableResultCache` kueri, sebagai berikut:

```
g.with('Neptune#enableResultCache', true)
 .V().has('genre','drama').in('likes')
```

Neptunus kemudian mengembalikan hasil kueri kepada Anda, dan juga menyimpannya dalam cache. Kemudian, Anda dapat mengakses hasil cache dengan mengeluarkan kueri yang persis sama lagi:

```
g.with('Neptune#enableResultCache', true)
 .V().has('genre','drama').in('likes')
```

Kunci cache yang mengidentifikasi hasil cache adalah string kueri itu sendiri, yaitu:

```
g.V().has('genre','drama').in('likes')
```

### Menggunakan `enableResultCacheWithTTL`
<a name="using-enableResultCacheWithTTL"></a>

Anda dapat menentukan berapa lama hasil kueri harus di-cache dengan menggunakan petunjuk `enableResultCacheWithTTL` kueri. Misalnya, kueri berikut menentukan bahwa hasil kueri akan kedaluwarsa setelah 120 detik:

```
g.with('Neptune#enableResultCacheWithTTL', 120)
 .V().has('genre','drama').in('likes')
```

Sekali lagi, kunci cache yang mengidentifikasi hasil cache adalah string kueri dasar:

```
g.V().has('genre','drama').in('likes')
```

Dan lagi, Anda dapat mengakses hasil cache menggunakan string kueri itu dengan petunjuk `enableResultCache` kueri:

```
g.with('Neptune#enableResultCache', true)
 .V().has('genre','drama').in('likes')
```

Jika 120 detik atau lebih telah berlalu sejak hasilnya di-cache, kueri itu akan mengembalikan hasil baru, dan menyimpannya dalam cache, tanpa ada time-to-live.

Anda juga dapat mengakses hasil cache dengan mengeluarkan kueri yang sama lagi dengan petunjuk `enableResultCacheWithTTL` kueri. Contoh:

```
g.with('Neptune#enableResultCacheWithTTL', 140)
 .V().has('genre','drama').in('likes')
```

Hingga 120 detik telah berlalu (yaitu, TTL saat ini berlaku), kueri baru ini menggunakan petunjuk `enableResultCacheWithTTL` kueri mengembalikan hasil yang di-cache. Setelah 120 detik, itu akan mengembalikan hasil baru dan menyimpannya dalam cache dengan time-to-live 140 detik.

**catatan**  
Jika hasil untuk kunci kueri sudah di-cache, maka kunci kueri yang sama dengan `enableResultCacheWithTTL` tidak menghasilkan hasil baru dan tidak berpengaruh pada hasil yang time-to-live saat ini di-cache.  
Jika hasil sebelumnya di-cache menggunakan`enableResultCache`, cache harus dibersihkan terlebih dahulu sebelum `enableResultCacheWithTTL` menghasilkan hasil baru dan menyimpannya untuk TTL yang ditentukannya.
Jika hasil sebelumnya di-cache menggunakan`enableResultCachewithTTL`, TTL sebelumnya harus kedaluwarsa terlebih dahulu sebelum `enableResultCacheWithTTL` menghasilkan hasil baru dan menyimpannya untuk TTL yang ditentukannya.

### Menggunakan `invalidateResultCacheKey`
<a name="using-invalidateResultCacheKey"></a>

Anda dapat menggunakan petunjuk `invalidateResultCacheKey` kueri untuk menghapus hasil cache untuk satu kueri tertentu. Contoh:

```
g.with('Neptune#invalidateResultCacheKey', true)
 .V().has('genre','drama').in('likes')
```

Kueri itu menghapus cache untuk kunci kueri`g.V().has('genre','drama').in('likes')`, dan mengembalikan hasil baru untuk kueri itu.

Anda juga dapat menggabungkan `invalidateResultCacheKey` dengan `enableResultCache` atau`enableResultCacheWithTTL`. Misalnya, kueri berikut menghapus hasil cache saat ini, menyimpan hasil baru, dan mengembalikannya:

```
g.with('Neptune#enableResultCache', true)
 .with('Neptune#invalidateResultCacheKey', true)
 .V().has('genre','drama').in('likes')
```

### Menggunakan `invalidateResultCache`
<a name="using-invalidateResultCache"></a>

Anda dapat menggunakan petunjuk `invalidateResultCache` kueri untuk menghapus semua hasil cache di cache hasil kueri. Contoh:

```
g.with('Neptune#invalidateResultCache', true)
 .V().has('genre','drama').in('likes')
```

Kueri itu menghapus seluruh cache hasil dan mengembalikan hasil baru untuk kueri.

Anda juga dapat menggabungkan `invalidateResultCache` dengan `enableResultCache` atau`enableResultCacheWithTTL`. Misalnya, kueri berikut menghapus seluruh cache hasil, menyimpan hasil baru untuk kueri ini, dan mengembalikannya:

```
g.with('Neptune#enableResultCache', true)
 .with('Neptune#invalidateResultCache', true)
 .V().has('genre','drama').in('likes')
```

## Paginasi hasil kueri yang di-cache
<a name="gremlin-results-cache-paginating"></a>

Misalkan Anda telah melakukan cache sejumlah besar hasil seperti ini:

```
g.with('Neptune#enableResultCache', true)
 .V().has('genre','drama').in('likes')
```

Sekarang misalkan Anda mengeluarkan kueri rentang berikut:

```
g.with('Neptune#enableResultCache', true)
 .V().has('genre','drama').in('likes').range(0,10)
```

Neptunus pertama kali mencari kunci cache penuh, yaitu. `g.V().has('genre','drama').in('likes').range(0,10)` Jika kunci itu tidak ada, Neptunus selanjutnya melihat apakah ada kunci untuk string kueri itu tanpa rentang (yaitu). `g.V().has('genre','drama').in('likes')` Ketika menemukan kunci itu, Neptunus kemudian mengambil sepuluh hasil pertama dari cache-nya, seperti yang ditentukan oleh rentang.

**catatan**  
Jika Anda menggunakan petunjuk `invalidateResultCacheKey` kueri dengan kueri yang memiliki rentang di akhir, Neptunus menghapus cache untuk kueri tanpa rentang jika tidak menemukan kecocokan yang tepat untuk kueri dengan rentang tersebut.

### Menggunakan `numResultsCached` dengan `.iterate()`
<a name="gremlin-results-cache-paginating-numResultsCached"></a>

Dengan menggunakan petunjuk `numResultsCached` kueri, Anda dapat mengisi cache hasil tanpa mengembalikan semua hasil yang di-cache, yang dapat berguna saat Anda memilih untuk membuat halaman sejumlah besar hasil.

Petunjuk `numResultsCached` kueri hanya berfungsi dengan kueri yang diakhiri dengan. `iterate()`

Misalnya, jika Anda ingin menyimpan 50 hasil pertama dari kueri sampel:

```
g.with("Neptune#enableResultCache", true)
 .with("Neptune#numResultsCached", 50)
 .V().has('genre','drama').in('likes').iterate()
```

Dalam hal ini kunci kueri dalam cache adalah:`g.with("Neptune#numResultsCached", 50).V().has('genre','drama').in('likes')`. Anda sekarang dapat mengambil sepuluh pertama dari hasil cache dengan kueri ini:

```
g.with("Neptune#enableResultCache", true)
 .with("Neptune#numResultsCached", 50)
 .V().has('genre','drama').in('likes').range(0, 10)
```

Dan, Anda dapat mengambil sepuluh hasil berikutnya dari kueri sebagai berikut:

```
g.with("Neptune#enableResultCache", true)
 .with("Neptune#numResultsCached", 50)
 .V().has('genre','drama').in('likes').range(10, 20)
```

Jangan lupa sertakan `numResultsCached` petunjuknya\$1 Ini adalah bagian penting dari kunci kueri dan karena itu harus ada untuk mengakses hasil cache.

**Beberapa hal yang perlu diingat saat menggunakan `numResultsCached`**
+ **Nomor yang Anda berikan `numResultsCached` diterapkan di akhir kueri.**   Ini berarti, misalnya, bahwa kueri berikut sebenarnya cache menghasilkan rentang`(1000, 1500)`:

  ```
  g.with("Neptune#enableResultCache", true)
   .with("Neptune#numResultsCached", 500)
   .V().range(1000, 2000).iterate()
  ```
+ **Nomor yang Anda berikan `numResultsCached` menentukan jumlah maksimum hasil untuk cache.**   Ini berarti, misalnya, bahwa kueri berikut sebenarnya cache menghasilkan rentang`(1000, 2000)`:

  ```
  g.with("Neptune#enableResultCache", true)
   .with("Neptune#numResultsCached", 100000)
   .V().range(1000, 2000).iterate()
  ```
+ **Hasil yang di-cache oleh kueri yang diakhiri dengan `.range().iterate()` memiliki jangkauannya sendiri.**   Misalnya, Anda menyimpan hasil cache menggunakan kueri seperti ini:

  ```
  g.with("Neptune#enableResultCache", true)
   .with("Neptune#numResultsCached", 500)
   .V().range(1000, 2000).iterate()
  ```

  Untuk mengambil 100 hasil pertama dari cache, Anda akan menulis kueri seperti ini:

  ```
  g.with("Neptune#enableResultCache", true)
   .with("Neptune#numResultsCached", 500)
   .V().range(1000, 2000).range(0, 100)
  ```

  Seratus hasil itu akan setara dengan hasil dari kueri dasar dalam kisaran tersebut`(1000, 1100)`.

## Kunci cache kueri yang digunakan untuk menemukan hasil cache
<a name="gremlin-results-cache-query-keys"></a>

Setelah hasil kueri di-cache, kueri berikutnya dengan *kunci cache kueri* yang sama mengambil hasil dari cache daripada menghasilkan yang baru. Kunci cache kueri dari kueri dievaluasi sebagai berikut:

1. Semua petunjuk kueri terkait cache diabaikan, kecuali untuk. `numResultsCached`

1. `iterate()`Langkah terakhir diabaikan.

1. Sisa kueri diurutkan sesuai dengan representasi kode byte.

String yang dihasilkan dicocokkan dengan indeks hasil kueri yang sudah ada di cache untuk menentukan apakah ada cache hit untuk kueri.

Misalnya, ambil kueri ini:

```
g.withSideEffect('Neptune#typePromotion', false).with("Neptune#enableResultCache", true)
 .with("Neptune#numResultsCached", 50)
 .V().has('genre','drama').in('likes').iterate()
```

Ini akan disimpan sebagai versi byte-code ini:

```
g.withSideEffect('Neptune#typePromotion', false)
 .with("Neptune#numResultsCached", 50)
 .V().has('genre','drama').in('likes')
```

## Pengecualian terkait dengan cache hasil
<a name="gremlin-results-cache-exceptions"></a>

Jika hasil kueri yang Anda coba cache terlalu besar untuk dimasukkan ke dalam memori cache bahkan setelah menghapus semua yang sebelumnya di-cache, Neptunus menimbulkan kesalahan. `QueryLimitExceededException` Tidak ada hasil yang dikembalikan, dan pengecualian menghasilkan pesan galat berikut:

```
The result size is larger than the allocated cache,
      please refer to results cache best practices for options to rerun the query.
```

Anda dapat menekan pesan ini menggunakan petunjuk `noCacheExceptions` kueri, sebagai berikut:

```
g.with('Neptune#enableResultCache', true)
 .with('Neptune#noCacheExceptions', true)
 .V().has('genre','drama').in('likes')
```

# Membuat peningkatan yang efisien dengan `mergeV()` Gremlin dan langkah-langkah `mergeE()`
<a name="gremlin-efficient-upserts"></a>

Upsert (atau sisipan bersyarat) menggunakan kembali simpul atau tepi jika sudah ada, atau membuatnya jika tidak. Upserts yang efisien dapat membuat perbedaan yang signifikan dalam kinerja kueri Gremlin.

Upserts memungkinkan Anda untuk menulis operasi penyisipan idempoten: tidak peduli berapa kali Anda menjalankan operasi seperti itu, hasil keseluruhannya sama. Ini berguna dalam skenario penulisan yang sangat bersamaan di mana modifikasi bersamaan pada bagian grafik yang sama dapat memaksa satu atau lebih transaksi untuk memutar kembali dengan a`ConcurrentModificationException`, sehingga memerlukan percobaan ulang.

Misalnya, kueri berikut meningkatkan simpul dengan menggunakan yang disediakan `Map` untuk pertama kali mencoba menemukan simpul dengan a of. `T.id` `"v-1"` Jika simpul itu ditemukan maka dikembalikan. Jika tidak ditemukan maka simpul dengan itu `id` dan properti dibuat melalui `onCreate` klausa.

```
g.mergeV([(id):'v-1']).
  option(onCreate, [(label): 'PERSON', 'email': 'person-1@example.org'])
```

## Batching upserts untuk meningkatkan throughput
<a name="gremlin-upserts-batching"></a>

Untuk skenario penulisan throughput tinggi, Anda dapat berantai `mergeV()` dan `mergeE()` melangkah bersama untuk meningkatkan simpul dan tepi dalam batch. Batching mengurangi overhead transaksional untuk menaikkan sejumlah besar simpul dan tepi. Anda kemudian dapat lebih meningkatkan throughput dengan meningkatkan permintaan batch secara paralel menggunakan beberapa klien.

Sebagai aturan praktis, kami merekomendasikan untuk meningkatkan sekitar 200 catatan per permintaan batch. Rekaman adalah satu titik atau label tepi atau properti. Sebuah simpul dengan label tunggal dan 4 properti, misalnya, membuat 5 catatan. Tepi dengan label dan properti tunggal menciptakan 2 catatan. Jika Anda ingin meningkatkan kumpulan simpul, masing-masing dengan label tunggal dan 4 properti, Anda harus mulai dengan ukuran batch 40, karena. `200 / (1 + 4) = 40`

Anda dapat bereksperimen dengan ukuran batch. 200 catatan per batch adalah titik awal yang baik, tetapi ukuran batch yang ideal mungkin lebih tinggi atau lebih rendah tergantung pada beban kerja Anda. Perhatikan, bagaimanapun, bahwa Neptunus dapat membatasi jumlah keseluruhan langkah Gremlin per permintaan. Batas ini tidak didokumentasikan, tetapi untuk berada di sisi yang aman, cobalah untuk memastikan bahwa permintaan Anda mengandung tidak lebih dari 1.500 langkah Gremlin. Neptunus dapat menolak permintaan batch besar dengan lebih dari 1.500 langkah.

Untuk meningkatkan throughput, Anda dapat meningkatkan batch secara paralel menggunakan beberapa klien (lihat). [Membuat Penulisan Gremlin Multithreaded yang Efisien](best-practices-gremlin-multithreaded-writes.md) Jumlah klien harus sama dengan jumlah thread pekerja pada instance penulis Neptunus Anda, yang biasanya 2 x jumlah CPUs v di server. Misalnya, sebuah `r5.8xlarge` instance memiliki 32 v CPUs dan 64 thread pekerja. Untuk skenario penulisan throughput tinggi menggunakan`r5.8xlarge`, Anda akan menggunakan 64 klien yang menulis batch upserts ke Neptunus secara paralel.

Setiap klien harus mengirimkan permintaan batch dan menunggu permintaan selesai sebelum mengirimkan permintaan lain. Meskipun beberapa klien berjalan secara paralel, setiap klien individu mengirimkan permintaan secara serial. Ini memastikan bahwa server disuplai dengan aliran permintaan yang stabil yang menempati semua thread pekerja tanpa membanjiri antrian permintaan sisi server (lihat). [Mengukur instans DB dalam sebuah klaster Neptune DB](feature-overview-db-clusters.md#feature-overview-sizing-instances)

## Cobalah untuk menghindari langkah-langkah yang menghasilkan banyak pelintas
<a name="gremlin-upserts-single-traverser"></a>

Ketika langkah Gremlin dijalankan, dibutuhkan traverser masuk, dan memancarkan satu atau lebih traverser keluaran. Jumlah pelintas yang dipancarkan oleh satu langkah menentukan berapa kali langkah berikutnya dijalankan.

Biasanya, ketika melakukan operasi batch Anda ingin setiap operasi, seperti upsert vertex A, untuk mengeksekusi sekali, sehingga urutan operasi terlihat seperti ini: upsert vertex A, kemudian upsert vertex B, kemudian upsert vertex C, dan seterusnya. Selama sebuah langkah membuat atau memodifikasi hanya satu elemen, ia hanya memancarkan satu traverser, dan langkah-langkah yang mewakili operasi berikutnya dijalankan hanya sekali. Jika, di sisi lain, sebuah operasi membuat atau memodifikasi lebih dari satu elemen, ia memancarkan beberapa pelintas, yang pada gilirannya menyebabkan langkah-langkah selanjutnya dieksekusi beberapa kali, sekali per traverser yang dipancarkan. Hal ini dapat mengakibatkan database melakukan pekerjaan tambahan yang tidak perlu, dan dalam beberapa kasus dapat mengakibatkan penciptaan simpul tambahan yang tidak diinginkan, tepi atau nilai properti.

Contoh bagaimana hal-hal bisa salah adalah dengan kueri seperti`g.V().addV()`. Kueri sederhana ini menambahkan simpul untuk setiap simpul yang ditemukan dalam grafik, karena `V()` memancarkan traverser untuk setiap simpul dalam grafik dan masing-masing pelintas tersebut memicu panggilan ke. `addV()`

Lihat [Mencampur upserts dan sisipan](#gremlin-upserts-and-inserts) cara menangani operasi yang dapat memancarkan banyak pelintas.

## Menaikkan simpul
<a name="gremlin-upserts-vertices"></a>

`mergeV()`Langkah ini dirancang khusus untuk menaikkan simpul. Dibutuhkan sebagai argumen a `Map` yang mewakili elemen untuk mencocokkan simpul yang ada dalam grafik, dan jika elemen tidak ditemukan, menggunakannya `Map` untuk membuat simpul baru. Langkah ini juga memungkinkan Anda untuk mengubah perilaku jika terjadi penciptaan atau kecocokan, di mana `option()` modulator dapat diterapkan dengan `Merge.onCreate` dan `Merge.onMatch` token untuk mengontrol perilaku masing-masing. Lihat [Dokumentasi TinkerPop Referensi](https://tinkerpop.apache.org/docs/current/reference/#mergevertex-step) untuk informasi lebih lanjut tentang cara menggunakan langkah ini.

Anda dapat menggunakan ID simpul untuk menentukan apakah ada simpul tertentu. Ini adalah pendekatan yang lebih disukai, karena Neptunus mengoptimalkan upserts untuk kasus penggunaan yang sangat bersamaan. IDs Sebagai contoh, kueri berikut membuat simpul dengan ID simpul yang diberikan jika belum ada, atau menggunakannya kembali jika memang demikian:

```
g.mergeV([(T.id): 'v-1']).
    option(onCreate, [(T.label): 'PERSON', email: 'person-1@example.org', age: 21]).
    option(onMatch, [age: 22]).
  id()
```

Perhatikan bahwa kueri ini diakhiri dengan `id()` langkah. Meskipun tidak sepenuhnya diperlukan untuk tujuan meningkatkan simpul, `id()` langkah ke akhir kueri upsert memastikan bahwa server tidak membuat serial semua properti simpul kembali ke klien, yang membantu mengurangi biaya penguncian kueri.

Atau, Anda dapat menggunakan properti simpul untuk mengidentifikasi simpul:

```
g.mergeV([email: 'person-1@example.org']).
    option(onCreate, [(T.label): 'PERSON', age: 21]).
    option(onMatch, [age: 22]).
  id()
```

Jika memungkinkan, gunakan sendiri yang disediakan pengguna IDs untuk membuat simpul, dan gunakan ini IDs untuk menentukan apakah simpul ada selama operasi upsert. Ini memungkinkan Neptunus mengoptimalkan upserts. Upsert berbasis ID dapat secara signifikan lebih efisien daripada upsert berbasis properti ketika modifikasi bersamaan adalah umum.

### Bagian atas simpul berantai
<a name="gremlin-upserts-vertices-chaining"></a>

Anda dapat menghubungkan bagian atas simpul bersama-sama untuk menyisipkannya dalam batch:

```
g.V('v-1')
 .fold()
 .coalesce(unfold(),
           addV('Person').property(id, 'v-1')
                         .property('email', 'person-1@example.org'))
 .V('v-2')
 .fold()
 .coalesce(unfold(),
           addV('Person').property(id, 'v-2')
                         .property('email', 'person-2@example.org'))
 .V('v-3')
 .fold()
 .coalesce(unfold(),
           addV('Person').property(id, 'v-3')
                         .property('email', 'person-3@example.org'))
 .id()
```

Atau, Anda juga dapat menggunakan `mergeV()` sintaks ini:

```
g.mergeV([(T.id): 'v-1', (T.label): 'PERSON', email: 'person-1@example.org']).
  mergeV([(T.id): 'v-2', (T.label): 'PERSON', email: 'person-2@example.org']).
  mergeV([(T.id): 'v-3', (T.label): 'PERSON', email: 'person-3@example.org'])
```

Namun, karena bentuk kueri ini menyertakan elemen dalam kriteria penelusuran yang berlebihan untuk pencarian dasar`id`, itu tidak seefisien kueri sebelumnya.

## Tepi yang menjulang
<a name="gremlin-upserts-edges"></a>

`mergeE()`Langkah ini dirancang khusus untuk menaikkan tepi. Dibutuhkan `Map` sebagai argumen yang mewakili elemen untuk mencocokkan tepi yang ada dalam grafik dan jika elemen tidak ditemukan, menggunakannya `Map` untuk membuat tepi baru. Langkah ini juga memungkinkan Anda untuk mengubah perilaku jika terjadi penciptaan atau kecocokan, di mana `option()` modulator dapat diterapkan dengan `Merge.onCreate` dan `Merge.onMatch` token untuk mengontrol perilaku masing-masing. Lihat [Dokumentasi TinkerPop Referensi](https://tinkerpop.apache.org/docs/current/reference/#mergeedge-step) untuk informasi lebih lanjut tentang cara menggunakan langkah ini.

Anda dapat menggunakan tepi IDs untuk menaikkan tepi dengan cara yang sama Anda menaikkan simpul menggunakan simpul kustom. IDs Sekali lagi, ini adalah pendekatan yang disukai karena memungkinkan Neptunus untuk mengoptimalkan kueri. Misalnya, kueri berikut membuat tepi berdasarkan ID tepinya jika belum ada, atau menggunakannya kembali jika ada. Kueri juga menggunakan simpul `Direction.from` dan `Direction.to` simpul jika perlu membuat tepi baru: IDs 

```
g.mergeE([(T.id): 'e-1']).
    option(onCreate, [(from): 'v-1', (to): 'v-2', weight: 1.0]).
    option(onMatch, [weight: 0.5]).
  id()
```

Perhatikan bahwa kueri ini diakhiri dengan `id()` langkah. Meskipun tidak sepenuhnya diperlukan untuk tujuan meningkatkan tepi, menambahkan `id()` langkah ke akhir kueri upsert memastikan bahwa server tidak membuat serial semua properti edge kembali ke klien, yang membantu mengurangi biaya penguncian kueri.

Banyak aplikasi menggunakan simpul khusus IDs, tetapi meninggalkan Neptunus untuk menghasilkan tepi. IDs Jika Anda tidak tahu ID tepi, tetapi Anda tahu `from` dan `to` simpulnya IDs, Anda dapat menggunakan kueri semacam ini untuk meningkatkan tepi:

```
g.mergeE([(from): 'v-1', (to): 'v-2', (T.label): 'KNOWS']).
  id()
```

Semua simpul yang direferensikan oleh `mergeE()` harus ada untuk langkah untuk membuat tepi.

### Bagian atas tepi rantai
<a name="gremlin-upserts-edges-chaining"></a>

Seperti halnya vertex upserts, sangat mudah untuk menggabungkan `mergeE()` langkah-langkah bersama untuk permintaan batch:

```
g.mergeE([(from): 'v-1', (to): 'v-2', (T.label): 'KNOWS']).
  mergeE([(from): 'v-2', (to): 'v-3', (T.label): 'KNOWS']).
  mergeE([(from): 'v-3', (to): 'v-4', (T.label): 'KNOWS']).
  id()
```

## Menggabungkan vertex dan edge upserts
<a name="gremlin-upserts-vertexes-and-edges"></a>

Terkadang Anda mungkin ingin meningkatkan kedua simpul dan tepi yang menghubungkannya. Anda dapat mencampur contoh batch yang disajikan di sini. Contoh berikut meningkatkan 3 simpul dan 2 tepi:

```
g.mergeV([(id):'v-1']).
    option(onCreate, [(label): 'PERSON', 'email': 'person-1@example.org']).
  mergeV([(id):'v-2']).
    option(onCreate, [(label): 'PERSON', 'email': 'person-2@example.org']).
  mergeV([(id):'v-3']).
    option(onCreate, [(label): 'PERSON', 'email': 'person-3@example.org']).
  mergeE([(from): 'v-1', (to): 'v-2', (T.label): 'KNOWS']).
  mergeE([(from): 'v-2', (to): 'v-3', (T.label): 'KNOWS']).
 id()
```

## Mencampur upserts dan sisipan
<a name="gremlin-upserts-and-inserts"></a>

Terkadang Anda mungkin ingin meningkatkan kedua simpul dan tepi yang menghubungkannya. Anda dapat mencampur contoh batch yang disajikan di sini. Contoh berikut meningkatkan 3 simpul dan 2 tepi:

Upserts biasanya melanjutkan satu elemen pada satu waktu. Jika Anda tetap berpegang pada pola upsert yang disajikan di sini, setiap operasi upsert memancarkan satu traverser, yang menyebabkan operasi berikutnya dijalankan hanya sekali.

Namun, terkadang Anda mungkin ingin mencampur upserts dengan sisipan. Ini bisa terjadi, misalnya, jika Anda menggunakan tepi untuk mewakili contoh tindakan atau peristiwa. Permintaan mungkin menggunakan upserts untuk memastikan bahwa semua simpul yang diperlukan ada, dan kemudian menggunakan sisipan untuk menambahkan tepi. Dengan permintaan semacam ini, perhatikan potensi jumlah pelintas yang dipancarkan dari setiap operasi.

Perhatikan contoh berikut, yang mencampur upsert dan sisipan untuk menambahkan tepi yang mewakili peristiwa ke dalam grafik:

```
// Fully optimized, but inserts too many edges
g.mergeV([(id):'v-1']).
    option(onCreate, [(label): 'PERSON', 'email': 'person-1@example.org']).
  mergeV([(id):'v-2']).
    option(onCreate, [(label): 'PERSON', 'email': 'person-2@example.org']).
  mergeV([(id):'v-3']).
    option(onCreate, [(label): 'PERSON', 'email': 'person-3@example.org']).
  mergeV([(T.id): 'c-1', (T.label): 'CITY', name: 'city-1']).
  V('p-1', 'p-2').
  addE('FOLLOWED').to(V('p-1')).
  V('p-1', 'p-2', 'p-3').
  addE('VISITED').to(V('c-1')).
  id()
```

Kueri harus menyisipkan 5 tepi: 2 tepi DIIKUTI dan 3 tepi VISITED. Namun, kueri sebagai tertulis menyisipkan 8 tepi: 2 DIIKUTI dan 6 DIKUNJUNGI. Alasan untuk ini adalah bahwa operasi yang menyisipkan 2 tepi FOLLOW memancarkan 2 traversers, menyebabkan operasi penyisipan berikutnya, yang menyisipkan 3 tepi, dieksekusi dua kali.

Perbaikannya adalah menambahkan `fold()` langkah setelah setiap operasi yang berpotensi memancarkan lebih dari satu traverser:

```
g.mergeV([(T.id): 'v-1', (T.label): 'PERSON', email: 'person-1@example.org']).
  mergeV([(T.id): 'v-2', (T.label): 'PERSON', email: 'person-2@example.org']).
  mergeV([(T.id): 'v-3', (T.label): 'PERSON', email: 'person-3@example.org']).
  mergeV([(T.id): 'c-1', (T.label): 'CITY', name: 'city-1']).
  V('p-1', 'p-2').
  addE('FOLLOWED').
    to(V('p-1')).
  fold().
  V('p-1', 'p-2', 'p-3').
  addE('VISITED').
    to(V('c-1')).
  id()
```

Di sini kita telah memasukkan `fold()` langkah setelah operasi yang menyisipkan tepi DIIKUTI. Ini menghasilkan traverser tunggal, yang kemudian menyebabkan operasi berikutnya dieksekusi hanya sekali.

Kelemahan dari pendekatan ini adalah bahwa query sekarang tidak sepenuhnya dioptimalkan, karena tidak `fold()` dioptimalkan. Operasi insert yang mengikuti sekarang juga tidak `fold()` akan dioptimalkan.

Jika Anda perlu menggunakan `fold()` untuk mengurangi jumlah pelintas atas nama langkah-langkah selanjutnya, cobalah untuk memesan operasi Anda sehingga yang paling murah menempati bagian kueri yang tidak dioptimalkan.

## Pengaturan Kardinalitas
<a name="gremlin-upserts-setting-cardinality"></a>

 Kardinalitas default untuk properti simpul di Neptunus diatur, yang berarti bahwa ketika menggunakan mergeV () nilai yang diberikan dalam peta semuanya akan diberikan kardinalitas itu. Untuk menggunakan kardinalitas tunggal, Anda harus eksplisit dalam penggunaannya. Mulai dari TinkerPop 3.7.0, ada sintaks baru yang memungkinkan kardinalitas diberikan sebagai bagian dari peta seperti yang ditunjukkan pada contoh berikut: 

```
g.mergeV([(T.id): '1234']).
  option(onMatch, ['age': single(20), 'name': single('alice'), 'city': set('miami')])
```

 Atau, Anda dapat menetapkan kardinalitas sebagai default untuk itu `option` sebagai berikut: 

```
// age and name are set to single cardinality by default
g.mergeV([(T.id): '1234']).
  option(onMatch, ['age': 22, 'name': 'alice', 'city': set('boston')], single)
```

 Ada lebih sedikit opsi untuk mengatur kardinalitas `mergeV()` sebelum versi 3.7.0. Pendekatan umum adalah kembali ke `property()` langkah sebagai berikut: 

```
g.mergeV([(T.id): '1234']). 
  option(onMatch, sideEffect(property(single,'age', 20).
  property(set,'city','miami')).constant([:]))
```

**catatan**  
 Pendekatan ini hanya akan bekerja dengan `mergeV()` ketika digunakan dengan langkah awal. Oleh karena itu Anda tidak akan dapat berantai `mergeV()` dalam satu traversal karena yang pertama `mergeV()` setelah langkah awal yang menggunakan sintaks ini akan menghasilkan kesalahan jika traverser yang masuk menjadi elemen grafik. Dalam hal ini, Anda ingin memecah `mergeV()` panggilan Anda menjadi beberapa permintaan di mana masing-masing dapat menjadi langkah awal. 

# Membuat peningkatan Gremlin yang efisien dengan `fold()/coalesce()/unfold()`
<a name="gremlin-efficient-upserts-pre-3.6"></a>

Upsert (atau sisipan bersyarat) menggunakan kembali simpul atau tepi jika sudah ada, atau membuatnya jika tidak. Upserts yang efisien dapat membuat perbedaan yang signifikan dalam kinerja kueri Gremlin.

Halaman ini menunjukkan bagaimana menggunakan pola `fold()/coalesce()/unfold()` Gremlin untuk membuat upserts yang efisien. Namun, dengan rilis TinkerPop versi 3.6.x yang diperkenalkan di Neptunus dalam versi mesin [1.2.1.0](engine-releases-1.2.1.0.md), langkah baru `mergeV()` dan lebih disukai dalam banyak kasus. `mergeE()` `fold()/coalesce()/unfold()`Pola yang dijelaskan di sini mungkin masih berguna dalam beberapa situasi yang kompleks, tetapi dalam penggunaan umum `mergeV()` dan `mergeE()` jika Anda bisa, seperti yang dijelaskan dalam[Membuat peningkatan yang efisien dengan `mergeV()` Gremlin dan langkah-langkah `mergeE()`](gremlin-efficient-upserts.md).

Upserts memungkinkan Anda untuk menulis operasi penyisipan idempoten: tidak peduli berapa kali Anda menjalankan operasi seperti itu, hasil keseluruhannya sama. Ini berguna dalam skenario penulisan yang sangat bersamaan di mana modifikasi bersamaan pada bagian grafik yang sama dapat memaksa satu atau lebih transaksi untuk memutar kembali dengan a`ConcurrentModificationException`, sehingga memerlukan percobaan ulang.

Misalnya, kueri berikut meningkatkan simpul dengan terlebih dahulu mencari simpul yang ditentukan dalam kumpulan data, dan kemudian melipat hasilnya ke dalam daftar. Dalam traversal pertama yang diberikan ke `coalesce()` langkah, kueri kemudian membuka daftar ini. Jika daftar yang dibuka tidak kosong, hasilnya dipancarkan dari. `coalesce()` Namun, jika `unfold()` mengembalikan koleksi kosong karena simpul saat ini tidak ada, lanjutkan `coalesce()` untuk mengevaluasi traversal kedua yang telah disediakan, dan dalam traversal kedua ini kueri membuat simpul yang hilang.

```
g.V('v-1').fold()
          .coalesce(
             unfold(),
             addV('Person').property(id, 'v-1')
                           .property('email', 'person-1@example.org')
           )
```

## Gunakan formulir yang dioptimalkan `coalesce()` untuk upserts
<a name="gremlin-upserts-pre-3.6-coalesce"></a>

Neptunus dapat mengoptimalkan `fold().coalesce(unfold(), ...)` idiom untuk membuat pembaruan throughput tinggi, tetapi pengoptimalan ini hanya berfungsi jika kedua bagian pengembalian baik simpul atau tepi `coalesce()` tetapi tidak ada yang lain. Jika Anda mencoba mengembalikan sesuatu yang berbeda, seperti properti, dari bagian mana pun`coalesce()`, pengoptimalan Neptunus tidak terjadi. Kueri mungkin berhasil, tetapi tidak akan berkinerja sebaik versi yang dioptimalkan, terutama terhadap kumpulan data besar.

Karena kueri upsert yang tidak dioptimalkan meningkatkan waktu eksekusi dan mengurangi throughput, ada baiknya menggunakan `explain` titik akhir Gremlin untuk menentukan apakah kueri upsert sepenuhnya dioptimalkan. Saat meninjau `explain` rencana, cari garis yang dimulai dengan `+ not converted into Neptune steps` dan`WARNING: >>`. Contoh:

```
+ not converted into Neptune steps: [FoldStep, CoalesceStep([[UnfoldStep], [AddEdgeSte...
WARNING: >> FoldStep << is not supported natively yet
```

Peringatan ini dapat membantu Anda mengidentifikasi bagian-bagian kueri yang mencegahnya dioptimalkan sepenuhnya.

Terkadang tidak mungkin untuk mengoptimalkan kueri sepenuhnya. Dalam situasi ini Anda harus mencoba meletakkan langkah-langkah yang tidak dapat dioptimalkan di akhir kueri, sehingga memungkinkan mesin untuk mengoptimalkan sebanyak mungkin langkah. Teknik ini digunakan dalam beberapa contoh batch upsert, di mana semua upsert yang dioptimalkan untuk satu set simpul atau tepi dilakukan sebelum modifikasi tambahan yang berpotensi tidak dioptimalkan diterapkan pada simpul atau tepi yang sama.

## Batching upserts untuk meningkatkan throughput
<a name="gremlin-upserts-pre-3.6-batching"></a>

Untuk skenario penulisan throughput tinggi, Anda dapat menggabungkan langkah-langkah upsert bersama-sama untuk meningkatkan simpul dan tepi dalam batch. Batching mengurangi overhead transaksional untuk menaikkan sejumlah besar simpul dan tepi. Anda kemudian dapat lebih meningkatkan throughput dengan meningkatkan permintaan batch secara paralel menggunakan beberapa klien.

Sebagai aturan praktis, kami merekomendasikan untuk meningkatkan sekitar 200 catatan per permintaan batch. Rekaman adalah satu titik atau label tepi atau properti. Sebuah simpul dengan label tunggal dan 4 properti, misalnya, membuat 5 catatan. Tepi dengan label dan properti tunggal menciptakan 2 catatan. Jika Anda ingin meningkatkan kumpulan simpul, masing-masing dengan label tunggal dan 4 properti, Anda harus mulai dengan ukuran batch 40, karena. `200 / (1 + 4) = 40`

Anda dapat bereksperimen dengan ukuran batch. 200 catatan per batch adalah titik awal yang baik, tetapi ukuran batch yang ideal mungkin lebih tinggi atau lebih rendah tergantung pada beban kerja Anda. Perhatikan, bagaimanapun, bahwa Neptunus dapat membatasi jumlah keseluruhan langkah Gremlin per permintaan. Batas ini tidak didokumentasikan, tetapi untuk berada di sisi yang aman cobalah untuk memastikan bahwa permintaan Anda mengandung tidak lebih dari 1500 langkah Gremlin. Neptunus dapat menolak permintaan batch besar dengan lebih dari 1500 langkah.

Untuk meningkatkan throughput, Anda dapat meningkatkan batch secara paralel menggunakan beberapa klien (lihat). [Membuat Penulisan Gremlin Multithreaded yang Efisien](best-practices-gremlin-multithreaded-writes.md) Jumlah klien harus sama dengan jumlah thread pekerja pada instance penulis Neptunus Anda, yang biasanya 2 x jumlah CPUs v di server. Misalnya, sebuah `r5.8xlarge` instance memiliki 32 v CPUs dan 64 thread pekerja. Untuk skenario penulisan throughput tinggi menggunakan`r5.8xlarge`, Anda akan menggunakan 64 klien yang menulis batch upserts ke Neptunus secara paralel.

Setiap klien harus mengirimkan permintaan batch dan menunggu permintaan selesai sebelum mengirimkan permintaan lain. Meskipun beberapa klien berjalan secara paralel, setiap klien individu mengirimkan permintaan secara serial. Ini memastikan bahwa server disuplai dengan aliran permintaan yang stabil yang menempati semua thread pekerja tanpa membanjiri antrian permintaan sisi server (lihat). [Mengukur instans DB dalam sebuah klaster Neptune DB](feature-overview-db-clusters.md#feature-overview-sizing-instances)

## Cobalah untuk menghindari langkah-langkah yang menghasilkan banyak pelintas
<a name="gremlin-upserts-pre-3.6-single-traverser"></a>

Ketika langkah Gremlin dijalankan, dibutuhkan traverser masuk, dan memancarkan satu atau lebih traverser keluaran. Jumlah pelintas yang dipancarkan oleh satu langkah menentukan berapa kali langkah berikutnya dijalankan.

Biasanya, ketika melakukan operasi batch Anda ingin setiap operasi, seperti upsert vertex A, untuk mengeksekusi sekali, sehingga urutan operasi terlihat seperti ini: upsert vertex A, kemudian upsert vertex B, kemudian upsert vertex C, dan seterusnya. Selama sebuah langkah membuat atau memodifikasi hanya satu elemen, ia hanya memancarkan satu traverser, dan langkah-langkah yang mewakili operasi berikutnya dijalankan hanya sekali. Jika, di sisi lain, sebuah operasi membuat atau memodifikasi lebih dari satu elemen, ia memancarkan beberapa pelintas, yang pada gilirannya menyebabkan langkah-langkah selanjutnya dieksekusi beberapa kali, sekali per traverser yang dipancarkan. Hal ini dapat mengakibatkan database melakukan pekerjaan tambahan yang tidak perlu, dan dalam beberapa kasus dapat mengakibatkan penciptaan simpul tambahan yang tidak diinginkan, tepi atau nilai properti.

Contoh bagaimana hal-hal bisa salah adalah dengan kueri seperti`g.V().addV()`. Kueri sederhana ini menambahkan simpul untuk setiap simpul yang ditemukan dalam grafik, karena `V()` memancarkan traverser untuk setiap simpul dalam grafik dan masing-masing pelintas tersebut memicu panggilan ke. `addV()`

Lihat [Mencampur upserts dan sisipan](#gremlin-upserts-pre-3.6-and-inserts) cara menangani operasi yang dapat memancarkan banyak pelintas.

## Menaikkan simpul
<a name="gremlin-upserts-pre-3.6-vertices"></a>

Anda dapat menggunakan ID simpul untuk menentukan apakah ada simpul yang sesuai. Ini adalah pendekatan yang lebih disukai, karena Neptunus mengoptimalkan upserts untuk kasus penggunaan yang sangat bersamaan. IDs Sebagai contoh, kueri berikut membuat simpul dengan ID simpul yang diberikan jika belum ada, atau menggunakannya kembali jika memang demikian:

```
g.V('v-1')
 .fold()
  .coalesce(unfold(),
            addV('Person').property(id, 'v-1')
                          .property('email', 'person-1@example.org'))
  .id()
```

Perhatikan bahwa kueri ini diakhiri dengan `id()` langkah. Meskipun tidak sepenuhnya diperlukan untuk tujuan meningkatkan simpul, menambahkan `id()` langkah ke akhir kueri upsert memastikan bahwa server tidak membuat serial semua properti simpul kembali ke klien, yang membantu mengurangi biaya penguncian kueri.

Atau, Anda dapat menggunakan properti simpul untuk menentukan apakah simpul itu ada:

```
g.V()
 .hasLabel('Person')
 .has('email', 'person-1@example.org')
 .fold()
 .coalesce(unfold(),
           addV('Person').property('email', 'person-1@example.org'))
 .id()
```

Jika memungkinkan, gunakan sendiri yang disediakan pengguna IDs untuk membuat simpul, dan gunakan ini IDs untuk menentukan apakah simpul ada selama operasi upsert. Ini memungkinkan Neptunus mengoptimalkan upserts di sekitar. IDs Peningkatan berbasis ID dapat secara signifikan lebih efisien daripada peningkatan berbasis properti dalam skenario modifikasi yang sangat bersamaan.

### Bagian atas simpul berantai
<a name="gremlin-upserts-pre-3.6-vertices-chaining"></a>

Anda dapat menghubungkan bagian atas simpul bersama-sama untuk menyisipkannya dalam batch:

```
g.V('v-1')
 .fold()
 .coalesce(unfold(),
           addV('Person').property(id, 'v-1')
                         .property('email', 'person-1@example.org'))
 .V('v-2')
 .fold()
 .coalesce(unfold(),
           addV('Person').property(id, 'v-2')
                         .property('email', 'person-2@example.org'))
 .V('v-3')
 .fold()
 .coalesce(unfold(),
           addV('Person').property(id, 'v-3')
                         .property('email', 'person-3@example.org'))
 .id()
```

## Tepi yang menjulang
<a name="gremlin-upserts-pre-3.6-edges"></a>

Anda dapat menggunakan tepi IDs untuk menaikkan tepi dengan cara yang sama Anda menaikkan simpul menggunakan simpul kustom. IDs Sekali lagi, ini adalah pendekatan yang disukai karena memungkinkan Neptunus untuk mengoptimalkan kueri. Misalnya, kueri berikut membuat tepi berdasarkan ID tepinya jika belum ada, atau menggunakannya kembali jika ada. Kueri juga menggunakan simpul `from` dan `to` simpul jika perlu membuat tepi baru. IDs 

```
g.E('e-1')
 .fold()
 .coalesce(unfold(),
           addE('KNOWS').from(V('v-1'))
                        .to(V('v-2'))
                        .property(id, 'e-1'))
 .id()
```

Banyak aplikasi menggunakan simpul khusus IDs, tetapi meninggalkan Neptunus untuk menghasilkan tepi. IDs Jika Anda tidak tahu ID tepi, tetapi Anda tahu `from` dan `to` simpul IDs, Anda dapat menggunakan formulasi ini untuk meningkatkan tepi:

```
g.V('v-1')
 .outE('KNOWS')
 .where(inV().hasId('v-2'))
 .fold()
 .coalesce(unfold(),
           addE('KNOWS').from(V('v-1'))
                        .to(V('v-2')))
 .id()
```

Perhatikan bahwa langkah simpul dalam `where()` klausa harus `inV()` (atau `outV()` jika Anda pernah `inE()` menemukan tepi), bukan. `otherV()` Jangan gunakan`otherV()`, di sini, atau kueri tidak akan dioptimalkan dan kinerja akan menurun. Misalnya, Neptunus tidak akan mengoptimalkan kueri berikut:

```
// Unoptimized upsert, because of otherV()
g.V('v-1')
 .outE('KNOWS')
 .where(otherV().hasId('v-2'))
 .fold()
 .coalesce(unfold(),
           addE('KNOWS').from(V('v-1'))
                        .to(V('v-2')))
 .id()
```

Jika Anda tidak tahu tepi atau simpul IDs di depan, Anda dapat meningkatkan menggunakan properti simpul:

```
g.V()
 .hasLabel('Person')
 .has('name', 'person-1')
 .outE('LIVES_IN')
 .where(inV().hasLabel('City').has('name', 'city-1'))
 .fold()
 .coalesce(unfold(),
           addE('LIVES_IN').from(V().hasLabel('Person')
                                    .has('name', 'person-1'))
                           .to(V().hasLabel('City')
                                  .has('name', 'city-1')))
 .id()
```

Seperti halnya vertex upserts, lebih baik menggunakan edge upserts berbasis ID menggunakan ID tepi atau `from` dan `to` simpul, daripada upsert berbasis properti IDs, sehingga Neptunus dapat sepenuhnya mengoptimalkan upsert.

### Memeriksa `from` dan `to` keberadaan simpul
<a name="gremlin-upserts-pre-3.6-edges-checking"></a>

Perhatikan konstruksi langkah-langkah yang membuat tepi baru:`addE().from().to()`. Konstruksi ini memastikan bahwa kueri memeriksa keberadaan simpul `from` dan `to` simpul. Jika salah satu dari ini tidak ada, kueri mengembalikan kesalahan sebagai berikut:

```
{
  "detailedMessage": "Encountered a traverser that does not map to a value for child...
  "code": "IllegalArgumentException",
  "requestId": "..."
}
```

Jika mungkin salah satu `from` atau `to` simpul tidak ada, Anda harus mencoba untuk meningkatkannya sebelum menaikkan tepi di antara keduanya. Lihat [Menggabungkan vertex dan edge upserts](#gremlin-upserts-pre-3.6-vertexes-and-edges).

Ada konstruksi alternatif untuk membuat tepi yang tidak boleh Anda gunakan:`V().addE().to()`. Itu hanya menambahkan tepi jika `from` simpul ada. Jika `to` simpul tidak ada, kueri menghasilkan kesalahan, seperti yang dijelaskan sebelumnya, tetapi jika `from` simpul tidak ada, itu diam-diam gagal memasukkan tepi, tanpa menghasilkan kesalahan apa pun. Misalnya, upsert berikut selesai tanpa menaikkan tepi jika `from` simpul tidak ada:

```
// Will not insert edge if from vertex does not exist
g.V('v-1')
 .outE('KNOWS')
 .where(inV().hasId('v-2'))
 .fold()
 .coalesce(unfold(),
           V('v-1').addE('KNOWS')
                   .to(V('v-2')))
 .id()
```

### Bagian atas tepi rantai
<a name="gremlin-upserts-pre-3.6-edges-chaining"></a>

Jika Anda ingin menghubungkan edge upserts bersama-sama untuk membuat permintaan batch, Anda harus memulai setiap upsert dengan pencarian simpul, bahkan jika Anda sudah tahu tepi. IDs

Jika Anda sudah tahu tepi IDs yang ingin Anda sertakan, dan simpul dan `to` simpul, Anda dapat menggunakan formulasi ini: IDs `from`

```
g.V('v-1')
 .outE('KNOWS')
 .hasId('e-1')
 .fold()
 .coalesce(unfold(),
           V('v-1').addE('KNOWS')
                   .to(V('v-2'))
                   .property(id, 'e-1'))
 .V('v-3')
 .outE('KNOWS')
 .hasId('e-2').fold()
 .coalesce(unfold(),
           V('v-3').addE('KNOWS')
                   .to(V('v-4'))
                   .property(id, 'e-2'))
 .V('v-5')
 .outE('KNOWS')
 .hasId('e-3')
 .fold()
 .coalesce(unfold(),
           V('v-5').addE('KNOWS')
                   .to(V('v-6'))
                   .property(id, 'e-3'))
 .id()
```

Mungkin skenario peningkatan tepi batch yang paling umum adalah Anda mengetahui `from` dan `to` simpulnya IDs, tetapi tidak tahu tepi IDs yang ingin Anda tingkatkan. Dalam hal ini, gunakan formulasi berikut:

```
g.V('v-1')
 .outE('KNOWS')
 .where(inV().hasId('v-2'))
 .fold()
 .coalesce(unfold(),
           V('v-1').addE('KNOWS')
                   .to(V('v-2')))

 .V('v-3')
 .outE('KNOWS')
 .where(inV().hasId('v-4'))
 .fold()
 .coalesce(unfold(),
           V('v-3').addE('KNOWS')
                   .to(V('v-4')))
 .V('v-5')
 .outE('KNOWS')
 .where(inV().hasId('v-6'))
 .fold()
 .coalesce(unfold(),
           V('v-5').addE('KNOWS').to(V('v-6')))
 .id()
```

Jika Anda mengetahui IDs tepi yang ingin Anda sertakan, tetapi tidak tahu simpulnya `from` dan IDs `to` simpulnya (ini tidak biasa), Anda dapat menggunakan formulasi ini:

```
g.V()
 .hasLabel('Person')
 .has('email', 'person-1@example.org')
 .outE('KNOWS')
 .hasId('e-1')
 .fold()
 .coalesce(unfold(),
           V().hasLabel('Person')
              .has('email', 'person-1@example.org')
              .addE('KNOWS')
              .to(V().hasLabel('Person')
                     .has('email', 'person-2@example.org'))
                     .property(id, 'e-1'))
 .V()
 .hasLabel('Person')
 .has('email', 'person-3@example.org')
 .outE('KNOWS')
 .hasId('e-2')
 .fold()
 .coalesce(unfold(),
           V().hasLabel('Person')
              .has('email', 'person-3@example.org')
              .addE('KNOWS')
              .to(V().hasLabel('Person')
                     .has('email', 'person-4@example.org'))
              .property(id, 'e-2'))
 .V()
 .hasLabel('Person')
 .has('email', 'person-5@example.org')
 .outE('KNOWS')
 .hasId('e-1')
 .fold()
 .coalesce(unfold(),
           V().hasLabel('Person')
              .has('email', 'person-5@example.org')
              .addE('KNOWS')
              .to(V().hasLabel('Person')
                     .has('email', 'person-6@example.org'))
                     .property(id, 'e-3'))
 .id()
```

## Menggabungkan vertex dan edge upserts
<a name="gremlin-upserts-pre-3.6-vertexes-and-edges"></a>

Terkadang Anda mungkin ingin meningkatkan kedua simpul dan tepi yang menghubungkannya. Anda dapat mencampur contoh batch yang disajikan di sini. Contoh berikut meningkatkan 3 simpul dan 2 tepi:

```
g.V('p-1')
 .fold()
 .coalesce(unfold(),
           addV('Person').property(id, 'p-1')
                         .property('email', 'person-1@example.org'))
 .V('p-2')
 .fold()
 .coalesce(unfold(),
           addV('Person').property(id, 'p-2')
                         .property('name', 'person-2@example.org'))
 .V('c-1')
 .fold()
 .coalesce(unfold(),
           addV('City').property(id, 'c-1')
                       .property('name', 'city-1'))
 .V('p-1')
 .outE('LIVES_IN')
 .where(inV().hasId('c-1'))
 .fold()
 .coalesce(unfold(),
           V('p-1').addE('LIVES_IN')
                   .to(V('c-1')))
 .V('p-2')
 .outE('LIVES_IN')
 .where(inV().hasId('c-1'))
 .fold()
 .coalesce(unfold(),
           V('p-2').addE('LIVES_IN')
                   .to(V('c-1')))
 .id()
```

## Mencampur upserts dan sisipan
<a name="gremlin-upserts-pre-3.6-and-inserts"></a>

Terkadang Anda mungkin ingin meningkatkan kedua simpul dan tepi yang menghubungkannya. Anda dapat mencampur contoh batch yang disajikan di sini. Contoh berikut meningkatkan 3 simpul dan 2 tepi:

Upserts biasanya melanjutkan satu elemen pada satu waktu. Jika Anda tetap berpegang pada pola upsert yang disajikan di sini, setiap operasi upsert memancarkan satu traverser, yang menyebabkan operasi berikutnya dijalankan hanya sekali.

Namun, terkadang Anda mungkin ingin mencampur upserts dengan sisipan. Ini bisa terjadi, misalnya, jika Anda menggunakan tepi untuk mewakili contoh tindakan atau peristiwa. Permintaan mungkin menggunakan upserts untuk memastikan bahwa semua simpul yang diperlukan ada, dan kemudian menggunakan sisipan untuk menambahkan tepi. Dengan permintaan semacam ini, perhatikan potensi jumlah pelintas yang dipancarkan dari setiap operasi.

Perhatikan contoh berikut, yang mencampur upsert dan sisipan untuk menambahkan tepi yang mewakili peristiwa ke dalam grafik:

```
// Fully optimized, but inserts too many edges
g.V('p-1')
 .fold()
 .coalesce(unfold(),
           addV('Person').property(id, 'p-1')
                         .property('email', 'person-1@example.org'))
 .V('p-2')
 .fold()
 .coalesce(unfold(),
           addV('Person').property(id, 'p-2')
                         .property('name', 'person-2@example.org'))
 .V('p-3')
 .fold()
 .coalesce(unfold(),
           addV('Person').property(id, 'p-3')
                         .property('name', 'person-3@example.org'))
 .V('c-1')
 .fold()
 .coalesce(unfold(),
           addV('City').property(id, 'c-1')
                       .property('name', 'city-1'))
 .V('p-1', 'p-2')
 .addE('FOLLOWED')
 .to(V('p-1'))
 .V('p-1', 'p-2', 'p-3')
 .addE('VISITED')
 .to(V('c-1'))
 .id()
```

Kueri harus menyisipkan 5 tepi: 2 tepi DIIKUTI dan 3 tepi VISITED. Namun, kueri sebagai tertulis menyisipkan 8 tepi: 2 DIIKUTI dan 6 DIKUNJUNGI. Alasan untuk ini adalah bahwa operasi yang menyisipkan 2 tepi FOLLOW memancarkan 2 traversers, menyebabkan operasi penyisipan berikutnya, yang menyisipkan 3 tepi, dieksekusi dua kali.

Perbaikannya adalah menambahkan `fold()` langkah setelah setiap operasi yang berpotensi memancarkan lebih dari satu traverser:

```
g.V('p-1')
 .fold()
 .coalesce(unfold(),
           addV('Person').property(id, 'p-1')
                         .property('email', 'person-1@example.org'))
 .V('p-2')
 .fold()
 .coalesce(unfold(),
           addV('Person').property(id, 'p-2').
                         .property('name', 'person-2@example.org'))
 .V('p-3')
 .fold()
 .coalesce(unfold(),
           addV('Person').property(id, 'p-3').
                         .property('name', 'person-3@example.org'))
 .V('c-1')
 .fold().
 .coalesce(unfold(),
            addV('City').property(id, 'c-1').
                        .property('name', 'city-1'))
 .V('p-1', 'p-2')
 .addE('FOLLOWED')
 .to(V('p-1'))
 .fold()
 .V('p-1', 'p-2', 'p-3')
 .addE('VISITED')
 .to(V('c-1')).
 .id()
```

Di sini kita telah memasukkan `fold()` langkah setelah operasi yang menyisipkan tepi DIIKUTI. Ini menghasilkan traverser tunggal, yang kemudian menyebabkan operasi berikutnya dieksekusi hanya sekali.

Kelemahan dari pendekatan ini adalah bahwa query sekarang tidak sepenuhnya dioptimalkan, karena tidak `fold()` dioptimalkan. Operasi insert yang mengikuti sekarang tidak `fold()` akan dioptimalkan.

Jika Anda perlu menggunakan `fold()` untuk mengurangi jumlah pelintas atas nama langkah-langkah selanjutnya, cobalah untuk memesan operasi Anda sehingga yang paling murah menempati bagian kueri yang tidak dioptimalkan.

## Upserts yang memodifikasi simpul dan tepi yang ada
<a name="gremlin-upserts-pre-3.6-that-modify"></a>

Terkadang Anda ingin membuat simpul atau tepi jika tidak ada, dan kemudian menambahkan atau memperbarui properti ke sana, terlepas dari apakah itu simpul atau tepi baru atau yang sudah ada.

Untuk menambah atau memodifikasi properti, gunakan `property()` langkah. Gunakan langkah ini di luar `coalesce()` langkah. Jika Anda mencoba memodifikasi properti simpul atau tepi yang ada di dalam `coalesce()` langkah, kueri mungkin tidak dioptimalkan oleh mesin kueri Neptunus.

Kueri berikut menambahkan atau memperbarui properti penghitung pada setiap simpul yang diupsert. Setiap `property()` langkah memiliki kardinalitas tunggal untuk memastikan bahwa nilai baru menggantikan nilai yang ada, daripada ditambahkan ke serangkaian nilai yang ada.

```
g.V('v-1')
 .fold()
 .coalesce(unfold(),
           addV('Person').property(id, 'v-1')
                         .property('email', 'person-1@example.org'))
 .property(single, 'counter', 1)
 .V('v-2')
 .fold()
 .coalesce(unfold(),
           addV('Person').property(id, 'v-2')
                         .property('email', 'person-2@example.org'))
 .property(single, 'counter', 2)
 .V('v-3')
 .fold()
 .coalesce(unfold(),
           addV('Person').property(id, 'v-3')
                         .property('email', 'person-3@example.org'))
 .property(single, 'counter', 3)
 .id()
```

Jika Anda memiliki nilai properti, seperti nilai `lastUpdated` stempel waktu, yang berlaku untuk semua elemen yang muncul, Anda dapat menambahkan atau memperbaruinya di akhir kueri:

```
g.V('v-1')
 .fold()
 .coalesce(unfold(),
           addV('Person').property(id, 'v-1')
                         .property('email', 'person-1@example.org'))
 .V('v-2').
 .fold().
 .coalesce(unfold(),
           addV('Person').property(id, 'v-2')
                         .property('email', 'person-2@example.org'))
 .V('v-3')
 .fold()
 .coalesce(unfold(),
           addV('Person').property(id, 'v-3')
                         .property('email', 'person-3@example.org'))
 .V('v-1', 'v-2', 'v-3')
 .property(single, 'lastUpdated', datetime('2020-02-08'))
 .id()
```

Jika ada kondisi tambahan yang menentukan apakah simpul atau tepi harus dimodifikasi lebih lanjut atau tidak, Anda dapat menggunakan `has()` langkah untuk memfilter elemen yang akan diterapkan modifikasi. Contoh berikut menggunakan `has()` langkah untuk memfilter simpul naik berdasarkan nilai properti mereka. `version` Kueri kemudian memperbarui ke 3 `version` dari setiap simpul yang `version` kurang dari 3:

```
g.V('v-1')
 .fold()
 .coalesce(unfold(),
           addV('Person').property(id, 'v-1')
                         .property('email', 'person-1@example.org')
                         .property('version', 3))
 .V('v-2')
 .fold()
 .coalesce(unfold(),
           addV('Person').property(id, 'v-2')
                         .property('email', 'person-2@example.org')
                         .property('version', 3))
 .V('v-3')
 .fold()
 .coalesce(unfold(),
           addV('Person').property(id, 'v-3')
                         .property('email', 'person-3@example.org')
                         .property('version', 3))
 .V('v-1', 'v-2', 'v-3')
 .has('version', lt(3))
 .property(single, 'version', 3)
 .id()
```

# Menganalisis eksekusi kueri Neptune menggunakan `explain` Gremlin
<a name="gremlin-explain"></a>

Amazon Neptune telah menambahkan fitur Gremlin bernama *explain*. Fitur ini adalah alat swalayan untuk memahami pendekatan eksekusi yang diambil oleh mesin Neptune. Anda memintanya dengan menambahkan parameter `explain` ke panggilan HTTP yang mengirimkan kueri Gremlin.

Fitur `explain` menyediakan informasi tentang struktur logis rencana eksekusi kueri. Anda dapat menggunakan informasi ini untuk mengidentifikasi potensi evaluasi dan hambatan eksekusi dan menyetel kueri Anda, seperti yang dijelaskan dalam [Menyetel kueri Gremlin](gremlin-traversal-tuning.md). Anda juga dapat menggunakan [petunjuk kueri](gremlin-query-hints.md) untuk meningkatkan rencana eksekusi kueri.

**Topics**
+ [

# Memahami bagaimana kueri Gremlin bekerja di Neptune
](gremlin-explain-background.md)
+ [

# Menggunakan API `explain` Gremlin di Neptune
](gremlin-explain-api.md)
+ [

# API `profile` Gremlin di Neptune
](gremlin-profile-api.md)
+ [

# Menyetel kueri Gremlin menggunakan `explain` dan `profile`
](gremlin-traversal-tuning.md)
+ [

# Dukungan langkah Gremlin asli di Amazon Neptune
](gremlin-step-support.md)

# Memahami bagaimana kueri Gremlin bekerja di Neptune
<a name="gremlin-explain-background"></a>

Untuk mengambil keuntungan penuh dari laporan `explain` dan `profile` Gremlin di Amazon Neptune, akan sangat membantu untuk memahami beberapa informasi latar belakang tentang kueri Gremlin.

**Topics**
+ [

# Pernyataan Gremlin di Neptune
](gremlin-explain-background-statements.md)
+ [

# Bagaimana Neptune memproses kueri Gremlin menggunakan indeks pernyataan
](gremlin-explain-background-indexing-examples.md)
+ [

# Bagaimana kueri Gremlin diproses di Neptune
](gremlin-explain-background-querying.md)

# Pernyataan Gremlin di Neptune
<a name="gremlin-explain-background-statements"></a>

Data grafik properti di Amazon Neptune terdiri dari pernyataan empat-posisi (quad). Masing-masing pernyataan ini merupakan unit atom individu data grafik properti. Untuk informasi selengkapnya, lihat [Model Data Grafik Neptune](feature-overview-data-model.md). Mirip dengan model data Resource Description Framework (RDF), empat posisi ini adalah sebagai berikut:
+ `subject (S)`
+ `predicate (P)`
+ `object (O)`
+ `graph (G)`

Setiap pernyataan adalah penegasan tentang satu sumber daya atau lebih. Misalnya, sebuah pernyataan dapat menegaskan adanya hubungan antara dua sumber daya, atau dapat melampirkan properti (pasangan nilai-kunci) ke beberapa sumber daya.

Anda dapat menganggap predikat sebagai kata kerja pernyataan, menggambarkan jenis hubungan atau properti. Objeknya adalah target hubungan, atau nilai properti. Posisi grafik adalah opsional dan dapat digunakan dalam berbagai cara. Untuk data grafik properti (PG) Neptune, bisa tidak digunakan (grafik null) atau digunakan untuk mewakili pengidentifikasi untuk edge. Satu set pernyataan dengan pengidentifikasi sumber daya bersama menciptakan grafik.

Ada tiga kelas pernyataan dalam model data grafik properti Neptune:

**Topics**
+ [Pernyataan Label Vertex Gremlin](#gremlin-explain-background-vertex-labels)
+ [Pernyataan Edge](#gremlin-explain-background-edge-statements)
+ [Pernyataan Properti](#gremlin-explain-background-property-statements)

## Pernyataan Label Vertex Gremlin
<a name="gremlin-explain-background-vertex-labels"></a>

Pernyataan label Vertex di Neptune melayani dua tujuan:
+ Mereka melacak label untuk vertex.
+ Kehadiran setidaknya satu dari pernyataan ini adalah yang menyiratkan adanya vertex tertentu dalam grafik.

Subjek dari pernyataan ini adalah pengidentifikasi vertex, dan objeknya adalah label, yang keduanya ditentukan oleh pengguna. Anda menggunakan predikat tetap khusus untuk pernyataan ini, ditampilkan sebagai `<~label>`, dan pengidentifikasi grafik default (grafik null), ditampilkan sebagai `<~>`.

Contohnya, pertimbangkan traversal `addV` berikut ini.

```
g.addV("Person").property(id, "v1")
```

Traversal ini menghasilkan pernyataan berikut yang ditambahkan ke grafik.

```
StatementEvent[Added(<v1> <~label> <Person> <~>) .]
```

## Pernyataan Gremlin Edge
<a name="gremlin-explain-background-edge-statements"></a>

Sebuah pernyataan edge Gremlin adalah yang menyiratkan adanya edge antara dua vertex dalam grafik di Neptune. Subjek (S) dari pernyataan edge adalah vertex `from` sumber. Predikat (P) adalah label edge yang disediakan pengguna. Objek (O) adalah vertex `to` target. Grafik (G) adalah pengenal edge yang disediakan pengguna.

Contohnya, pertimbangkan traversal `addE` berikut ini.

```
g.addE("knows").from(V("v1")).to(V("v2")).property(id, "e1")
```

Traversal menghasilkan pernyataan berikut yang ditambahkan ke grafik.

```
StatementEvent[Added(<v1> <knows> <v2> <e1>) .]
```

## Pernyataan Properti Gremlin
<a name="gremlin-explain-background-property-statements"></a>

Sebuah pernyataan properti Gremlin di Neptune menegaskan nilai properti individu untuk vertex atau edge. Subjek adalah pengidentifikasi vertex atau edge yang disediakan pengguna. Predikat adalah nama properti (kunci), dan objek adalah nilai properti individu. Grafik (G) adalah sekali lagi pengidentifikasi grafik default, grafik null, ditampilkan sebagai `<~>`.

Perhatikan contoh properti simpul berikut.

```
g.V("v1").property("name", "John")
```

Pernyataan ini menghasilkan berikut ini.

```
StatementEvent[Added(<v1> <name> "John" <~>) .]
```

Pernyataan properti berbeda dari yang lain dalam hal bahwa objek mereka adalah nilai primitif (`string`, `date`, `byte`, `short`, `int`, `long`, `float`, atau `double`). Objek mereka bukan pengidentifikasi sumber daya yang dapat digunakan sebagai subjek penegasan lain.

Untuk multi-properti, setiap nilai properti individu dalam set menerima pernyataannya sendiri.

```
g.V("v1").property(set, "phone", "956-424-2563").property(set, "phone", "956-354-3692 (tel:9563543692)")
```

Hal ini menyebabkan hal berikut ini.

```
StatementEvent[Added(<v1> <phone> "956-424-2563" <~>) .]
StatementEvent[Added(<v1> <phone> "956-354-3692" <~>) .]
```

Properti tepi ditangani mirip dengan properti simpul, tetapi gunakan pengenal tepi di posisi (S). Misalnya, menambahkan properti ke tepi:

```
g.E("e1").property("weight", 0.8)
```

Ini menghasilkan pernyataan berikut yang ditambahkan ke grafik.

```
StatementEvent[Added(<e1> <weight> 0.8 <~>) .]
```

# Bagaimana Neptune memproses kueri Gremlin menggunakan indeks pernyataan
<a name="gremlin-explain-background-indexing-examples"></a>

Pernyataam diakses di Amazon Neptune dengan cara tiga indeks pernyataan, seperti yang dijelaskan dalam [Bagaimana Pernyataan Diindeks di Neptune](feature-overview-storage-indexing.md). Neptune mengekstrak sebuah *pola* pernyataan dari kueri Gremlin di mana beberapa posisi diketahui, dan sisanya dibiarkan untuk penemuan oleh pencarian indeks.

Neptune mengasumsikan bahwa ukuran skema grafik properti tidak besar. Ini berarti bahwa jumlah label edge yang berbeda dan nama properti cukup rendah, sehingga jumlah predikat yang berbeda rendah. Neptune melacak predikat yang berbeda dalam indeks terpisah. Menggunakan cache predikat ini untuk melakukan pemindaian serikat `{ all P x POGS }` daripada menggunakan indeks OSGP. Menghindari kebutuhan untuk indeks OSGP traversal terbalik menghemat ruang penyimpanan dan throughput beban.

Neptunus Explain/Profile Gremlin API memungkinkan Anda mendapatkan jumlah predikat dalam grafik Anda. Anda kemudian dapat menentukan apakah aplikasi Anda membatalkan asumsi Neptune bahwa skema grafik properti Anda kecil.

Contoh berikut membantu menggambarkan bagaimana Neptune menggunakan indeks untuk memproses kueri Gremlin.

**Pertanyaan: Apa label simpul? `v1`**

```
  Gremlin code:      g.V('v1').label()
  Pattern:           (<v1>, <~label>, ?, ?)
  Known positions:   SP
  Lookup positions:  OG
  Index:             SPOG
  Key range:         <v1>:<~label>:*
```

**Pertanyaan: Apa tepi luar 'tahu' dari simpul? `v1`**

```
  Gremlin code:      g.V('v1').out('knows')
  Pattern:           (<v1>, <knows>, ?, ?)
  Known positions:   SP
  Lookup positions:  OG
  Index:             SPOG
  Key range:         <v1>:<knows>:*
```

**Pertanyaan: Simpul mana yang memiliki label `Person` simpul?**

```
  Gremlin code:      g.V().hasLabel('Person')
  Pattern:           (?, <~label>, <Person>, <~>)
  Known positions:   POG
  Lookup positions:  S
  Index:             POGS
  Key range:         <~label>:<Person>:<~>:*
```

**Pertanyaan: Apa from/to simpul dari tepi yang diberikan? `e1`**

```
  Gremlin code:      g.E('e1').bothV()
  Pattern:           (?, ?, ?, <e1>)
  Known positions:   G
  Lookup positions:  SPO
  Index:             GPSO
  Key range:         <e1>:*
```

Satu indeks pernyataan yang **tidak** Neptune miliki adalah indeks OSGP traversal terbalik. Indeks ini dapat digunakan untuk mengumpulkan semua edge masuk di semua label edge, seperti dalam contoh berikut.

**Pertanyaan: Apa `v1` simpul yang berdekatan yang masuk?**

```
  Gremlin code:      g.V('v1').in()
  Pattern:           (?, ?, <v1>, ?)
  Known positions:   O
  Lookup positions:  SPG
  Index:             OSGP  // <-- Index does not exist
```

# Bagaimana kueri Gremlin diproses di Neptune
<a name="gremlin-explain-background-querying"></a>

Di Amazon Neptune, traversal yang lebih kompleks dapat diwakili oleh serangkaian pola yang menciptakan relasi berdasarkan definisi variabel bernama yang dapat dibagi di seluruh pola untuk membuat gabungan. Seperti yang ditunjukkan dalam contoh berikut.

**Pertanyaan: Apa lingkungan dua hop dari vertex? `v1`**

```
  Gremlin code:      g.V(‘v1’).out('knows').out('knows').path()
  Pattern:           (?1=<v1>, <knows>, ?2, ?) X Pattern(?2, <knows>, ?3, ?)

  The pattern produces a three-column relation (?1, ?2, ?3) like this:
                     ?1     ?2     ?3
                     ================
                     v1     v2     v3
                     v1     v2     v4
                     v1     v5     v6
```

Dengan berbagi variabel `?2` di dua pola (pada posisi O dalam pola pertama dan posisi S dari pola kedua), Anda membuat gabungan dari tetangga hop pertama ke tetangga hop kedua. [Setiap solusi Neptunus memiliki binding untuk tiga variabel bernama, yang dapat digunakan untuk membuat ulang TinkerPop Traverser (termasuk informasi jalur).](http://tinkerpop.apache.org/docs/current/reference/#_the_traverser)

```
```

[Langkah pertama dalam pemrosesan kueri Gremlin adalah mengurai kueri menjadi objek TinkerPop [Traversal](http://tinkerpop.apache.org/docs/current/reference/#traversal), yang terdiri dari serangkaian langkah. TinkerPop ](http://tinkerpop.apache.org/docs/current/reference/#graph-traversal-steps) Langkah-langkah ini, yang merupakan bagian dari [ TinkerPop proyek Apache](http://tinkerpop.apache.org/) open-source, adalah operator logis dan fisik yang menyusun traversal Gremlin dalam implementasi referensi. Keduanya digunakan untuk mewakili model kueri. Keduanya adalah operator yang dapat dieksekusi yang dapat menghasilkan solusi sesuai dengan semantik operator yang mereka wakili. Misalnya, keduanya `.V()` diwakili dan dieksekusi oleh TinkerPop [GraphStep](http://tinkerpop.apache.org/docs/current/reference/#graph-step).

Karena off-the-shelf TinkerPop langkah-langkah ini dapat dieksekusi, TinkerPop Traversal semacam itu dapat mengeksekusi kueri Gremlin apa pun dan menghasilkan jawaban yang benar. Namun, ketika dieksekusi terhadap grafik besar, TinkerPop langkah-langkah terkadang bisa sangat tidak efisien dan lambat. Alih-alih menggunakannya, Neptune mencoba mengubah traversal menjadi bentuk deklaratif yang terdiri dari grup pola, seperti yang dijelaskan sebelumnya.

Neptune saat ini tidak mendukung semua operator (langkah) Gremlin di mesin kueri aslinya. Jadi Neptune mencoba melakukan collaps pada sebanyak mungkin langkah ke dalam satu `NeptuneGraphQueryStep`, yang berisi rencana kueri logis deklaratif untuk semua langkah-langkah yang telah dikonversi. Idealnya, semua langkah dikonversi. Tetapi ketika sebuah langkah ditemukan yang tidak dapat dikonversi, Neptunus keluar dari eksekusi asli dan menunda semua eksekusi kueri dari titik itu ke langkah-langkahnya. TinkerPop Neptune tidak mencoba untuk menjalin masuk dan keluar dari eksekusi asli.

Setelah langkah-langkah diterjemahkan ke dalam rencana kueri logis, Neptune menjalankan serangkaian pengoptimal kueri yang menulis ulang rencana kueri berdasarkan analisis statis dan perkiraan kardinalitas. Pengoptimal ini melakukan hal-hal seperti mengatur ulang operator berdasarkan jumlah rentang, memangkas operator yang tidak perlu atau berlebihan, mengatur ulang filter, mendorong operator ke dalam kelompok yang berbeda, dan sebagainya.

Setelah rencana kueri yang dioptimalkan diproduksi, Neptune menciptakan alur operator fisik yang melakukan pekerjaan mengeksekusi kueri. Ini termasuk membaca data dari indeks pernyataan, melakukan penggabungan berbagai jenis, penyaringan, pengurutan, dan sebagainya. Pipeline menghasilkan aliran solusi yang kemudian diubah kembali menjadi aliran objek TinkerPop Traverser.

## Serialisasi hasil kueri
<a name="gremlin-explain-background-querying-serialization"></a>

Amazon Neptunus saat ini mengandalkan TinkerPop serializer pesan respons untuk mengonversi hasil kueri TinkerPop (Traversers) menjadi data serial untuk dikirim melalui kabel kembali ke klien. Format serialisasi ini cenderung cukup verbose.

Sebagai contoh, untuk melakukan serialisasi hasil dari kueri vertex seperti `g.V().limit(1)`, mesin kueri Neptune harus melakukan pencarian tunggal untuk memproduksi hasil kueri. Namun, serializer `GraphSON` akan melakukan sejumlah besar pencarian tambahan untuk mengemas vertex ke dalam format serialisasi. Serializer harus melakukan satu pencarian untuk mendapatkan label, satu pencarian untuk mendapatkan kunci properti, dan satu pencarian per kunci properti untuk vertex untuk mendapatkan semua nilai untuk setiap kunci.

Beberapa format serialisasi lebih efisien, tetapi semua memerlukan pencarian tambahan. Selain itu, TinkerPop serializer tidak mencoba menghindari penelusuran duplikat, seringkali mengakibatkan banyak pencarian diulang secara tidak perlu.

Hal ini membuat sangat penting untuk menulis kueri Anda sehingga mereka meminta secara khusus hanya untuk informasi yang mereka butuhkan. Misalnya, `g.V().limit(1).id()` akan mengembalikan hanya ID vertex dan menghilangkan semua pencarian serializer tambahan. [API `profile` Gremlin di Neptune](gremlin-profile-api.md) memungkinkan Anda untuk melihat berapa banyak panggilan pencarian yang dilakukan selama eksekusi kueri dan selama serialisasi.

# Menggunakan API `explain` Gremlin di Neptune
<a name="gremlin-explain-api"></a>

API `explain` Gremlin Amazon Neptune mengembalikan rencana kueri yang akan dieksekusi jika kueri tertentu dijalankan. Karena API tidak benar-benar menjalankan kueri, rencana dikembalikan hampir seketika.

Ini berbeda dari langkah TinkerPop .explain () sehingga dapat melaporkan informasi khusus ke mesin Neptunus.

## Informasi yang terkandung dalam laporan `explain` Gremlin
<a name="gremlin-explain-api-results"></a>

Laporan `explain` berisi informasi berikut:
+ String kueri seperti yang diminta.
+ **Traversal asli.** Ini adalah objek TinkerPop Traversal yang dihasilkan dengan mengurai string kueri menjadi beberapa TinkerPop langkah. Ini setara dengan kueri asli yang dihasilkan dengan menjalankan `.explain()` kueri terhadap kueri TinkerPop TinkerGraph.
+ **Traversal yang dikonversi.** Ini adalah Traversal Neptunus yang dihasilkan dengan mengubah TinkerPop Traversal menjadi representasi rencana kueri logis Neptunus. Dalam banyak kasus, seluruh TinkerPop traversal diubah menjadi dua langkah Neptunus: satu yang mengeksekusi seluruh query `NeptuneGraphQueryStep` () dan satu yang mengubah output mesin kueri Neptunus kembali menjadi Traversers (). TinkerPop `NeptuneTraverserConverterStep`
+ **Traversal yang dioptimalkan.** Ini adalah versi yang dioptimalkan dari rencana kueri Neptune setelah dijalankan melalui serangkaian pengoptimalan mengurangi kerja statis yang menulis ulang kueri berdasarkan analisis statis dan perkiraan kardinalitas. Pengoptimal ini melakukan hal-hal seperti mengatur ulang operator berdasarkan jumlah rentang, memangkas operator yang tidak perlu atau berlebihan, mengatur ulang filter, mendorong operator ke dalam kelompok yang berbeda, dan sebagainya.
+ **Hitungan predikat.** Karena strategi pengindeksan Neptune yang dijelaskan sebelumnya, memiliki sejumlah besar predikat yang berbeda dapat menyebabkan masalah performa. Hal ini terutama berlaku untuk kueri yang menggunakan operator traversal terbalik tanpa label edge (`.in` atau `.both`). Jika operator tersebut digunakan dan jumlah predikat cukup tinggi, `explain` menampilkan pesan peringatan.
+ **Informasi DFE.** Ketika mesin alternatif DFE diaktifkan, komponen traversal berikut mungkin muncul dalam traversal yang dioptimalkan:
  + **`DFEStep`**— Langkah DFE Neptunus yang dioptimalkan dalam traversal yang berisi anak. `DFENode` `DFEStep`merupakan bagian dari rencana kueri yang dijalankan di mesin DFE.
  + **`DFENode`**— Berisi representasi menengah sebagai satu atau lebih anak`DFEJoinGroupNodes`.
  + **`DFEJoinGroupNode`**— Merupakan gabungan dari satu atau lebih `DFENode` atau `DFEJoinGroupNode` elemen.
  + **`NeptuneInterleavingStep`**— Langkah DFE Neptunus yang dioptimalkan dalam traversal yang berisi anak. `DFEStep`

    Juga berisi `stepInfo` elemen yang berisi informasi tentang traversal, seperti elemen perbatasan, elemen jalur yang digunakan, dan sebagainya. Informasi ini digunakan untuk memproses anak`DFEStep`.

  Cara mudah untuk mengetahui apakah permintaan Anda sedang dievaluasi oleh DFE adalah memeriksa apakah output `explain` berisi `DFEStep`. Setiap bagian dari traversal yang bukan bagian dari tidak `DFEStep` akan dieksekusi oleh DFE dan akan dieksekusi oleh mesin. TinkerPop 

  Lihat [Contoh dengan DFE diaktifkan](#gremlin-explain-dfe) untuk laporan contoh.

## Sintaks `explain` Gremlin
<a name="gremlin-explain-api-syntax"></a>

Sintaks API `explain` sama seperti untuk API HTTP untuk kueri, kecuali bahwa ia menggunakan `/gremlin/explain` sebagai titik akhir, bukan `/gremlin`, seperti pada contoh berikut.

```
curl -X POST https://your-neptune-endpoint:port/gremlin/explain -d '{"gremlin":"g.V().limit(1)"}'
```

Kueri sebelumnya akan menghasilkan output berikut.

```
*******************************************************
                Neptune Gremlin Explain
*******************************************************

Query String
============
g.V().limit(1)

Original Traversal
==================
[GraphStep(vertex,[]), RangeGlobalStep(0,1)]

Converted Traversal
===================
Neptune steps:
[
    NeptuneGraphQueryStep(Vertex) {
        JoinGroupNode {
            PatternNode[(?1, <~label>, ?2, <~>) . project distinct ?1 .]
        }, finishers=[limit(1)], annotations={path=[Vertex(?1):GraphStep], maxVarId=3}
    },
    NeptuneTraverserConverterStep
]

Optimized Traversal
===================
Neptune steps:
[
    NeptuneGraphQueryStep(Vertex) {
        JoinGroupNode {
            PatternNode[(?1, <~label>, ?2, <~>) . project distinct ?1 .], {estimatedCardinality=INFINITY}
        }, finishers=[limit(1)], annotations={path=[Vertex(?1):GraphStep], maxVarId=3}
    },
    NeptuneTraverserConverterStep
]

Predicates
==========
# of predicates: 18
```

## Langkah Belum Dikonversi TinkerPop
<a name="gremlin-explain-unconverted-steps"></a>

Idealnya, semua TinkerPop langkah dalam traversal memiliki cakupan operator Neptunus asli. Ketika ini tidak terjadi, Neptunus kembali TinkerPop pada eksekusi langkah untuk kesenjangan dalam jangkauan operatornya. Jika traversal menggunakan langkah yang belum Neptune miliki cakupan aslinya, laporan `explain` menampilkan peringatan yang menunjukkan dimana kesenjangan terjadi.

Ketika sebuah langkah tanpa operator Neptunus asli yang sesuai ditemukan, seluruh traversal dari titik itu ke depan dijalankan TinkerPop menggunakan langkah-langkah, bahkan jika langkah selanjutnya memang memiliki operator Neptunus asli.

Pengecualian untuk ini adalah ketika pencarian teks lengkap Neptune dipanggil. NeptuneSearchStep Mengimplementasikan langkah-langkah tanpa padanan asli sebagai langkah pencarian teks lengkap.

## Contoh output `explain` di mana semua langkah dalam kueri memiliki ekuivalen asli
<a name="gremlin-explain-all-steps-converted"></a>

Berikut ini adalah contoh laporan `explain` untuk kueri di mana semua langkah memiliki ekuivalen asli:

```
*******************************************************
                Neptune Gremlin Explain
*******************************************************

Query String
============
g.V().out()

Original Traversal
==================
[GraphStep(vertex,[]), VertexStep(OUT,vertex)]

Converted Traversal
===================
Neptune steps:
[
    NeptuneGraphQueryStep(Vertex) {
        JoinGroupNode {
            PatternNode[(?1, <~label>, ?2, <~>) . project distinct ?1 .]
            PatternNode[(?1, ?5, ?3, ?6) . project ?1,?3 . IsEdgeIdFilter(?6) .]
            PatternNode[(?3, <~label>, ?4, <~>) . project ask .]
        }, annotations={path=[Vertex(?1):GraphStep, Vertex(?3):VertexStep], maxVarId=7}
    },
    NeptuneTraverserConverterStep
]

Optimized Traversal
===================
Neptune steps:
[
    NeptuneGraphQueryStep(Vertex) {
        JoinGroupNode {
            PatternNode[(?1, ?5, ?3, ?6) . project ?1,?3 . IsEdgeIdFilter(?6) .], {estimatedCardinality=INFINITY}
        }, annotations={path=[Vertex(?1):GraphStep, Vertex(?3):VertexStep], maxVarId=7}
    },
    NeptuneTraverserConverterStep
]

Predicates
==========
# of predicates: 18
```

## Contoh di mana beberapa langkah dalam kueri tidak memiliki ekuivalen asli
<a name="gremlin-explain-not-all-steps-converted"></a>

Neptune menangani `GraphStep` dan `VertexStep` secara native, tetapi jika Anda memperkenalkan `FoldStep` dan `UnfoldStep`, output `explain` yang dihasilkan berbeda:

```
*******************************************************
                Neptune Gremlin Explain
*******************************************************

Query String
============
g.V().fold().unfold().out()

Original Traversal
==================
[GraphStep(vertex,[]), FoldStep, UnfoldStep, VertexStep(OUT,vertex)]

Converted Traversal
===================
Neptune steps:
[
    NeptuneGraphQueryStep(Vertex) {
        JoinGroupNode {
            PatternNode[(?1, <~label>, ?2, <~>) . project distinct ?1 .]
        }, annotations={path=[Vertex(?1):GraphStep], maxVarId=3}
    },
    NeptuneTraverserConverterStep
]
+ not converted into Neptune steps: [FoldStep, UnfoldStep, VertexStep(OUT,vertex)]

Optimized Traversal
===================
Neptune steps:
[
    NeptuneGraphQueryStep(Vertex) {
        JoinGroupNode {
            PatternNode[(?1, <~label>, ?2, <~>) . project distinct ?1 .], {estimatedCardinality=INFINITY}
        }, annotations={path=[Vertex(?1):GraphStep], maxVarId=3}
    },
    NeptuneTraverserConverterStep,
    NeptuneMemoryTrackerStep
]
+ not converted into Neptune steps: [FoldStep, UnfoldStep, VertexStep(OUT,vertex)]

WARNING: >> FoldStep << is not supported natively yet
```

Dalam hal ini, `FoldStep` menghentikan Anda dari eksekusi asli. Namun bahkan `VertexStep` berikutnya tidak lagi ditangani secara native karena muncul hilir dari langkah `Fold/Unfold`.

Untuk kinerja dan penghematan biaya, penting bagi Anda untuk mencoba merumuskan traversal sehingga jumlah maksimum pekerjaan yang mungkin dilakukan secara asli di dalam mesin kueri Neptunus, bukan dengan implementasi langkah. TinkerPop 

## Contoh kueri yang menggunakan Neptunus full-text-search
<a name="gremlin-explain-full-text-search-steps"></a>

Kueri berikut menggunakan pencarian teks lengkap Neptune:

```
g.withSideEffect("Neptune#fts.endpoint", "some_endpoint")
  .V()
  .tail(100)
  .has("Neptune#fts mark*")
  -------
  .has("name", "Neptune#fts mark*")
  .has("Person", "name", "Neptune#fts mark*")
```

Bagian `.has("name", "Neptune#fts mark*")` membatasi pencarian ke vertex dengan `name`, sementara `.has("Person", "name", "Neptune#fts mark*")` membatasi pencarian ke vertex dengan `name` dan label `Person`. Hal ini menghasilkan traversal berikut di laporan `explain`:

```
Final Traversal
[NeptuneGraphQueryStep(Vertex) {
    JoinGroupNode {
        PatternNode[(?1, termid(1,URI), ?2, termid(0,URI)) . project distinct ?1 .], {estimatedCardinality=INFINITY}
    }, annotations={path=[Vertex(?1):GraphStep], maxVarId=4}
}, NeptuneTraverserConverterStep, NeptuneTailGlobalStep(10), NeptuneTinkerpopTraverserConverterStep, NeptuneSearchStep {
    JoinGroupNode {
        SearchNode[(idVar=?3, query=mark*, field=name) . project ask .], {endpoint=some_endpoint}
    }
    JoinGroupNode {
        SearchNode[(idVar=?3, query=mark*, field=name) . project ask .], {endpoint=some_endpoint}
    }
}]
```

## Contoh penggunaan `explain` saat DFE diaktifkan
<a name="gremlin-explain-dfe"></a>

Berikut ini adalah contoh laporan `explain` ketika mesin kueri alternatif DFE diaktifkan:

```
*******************************************************
                Neptune Gremlin Explain
*******************************************************

Query String
============

g.V().as("a").out().has("name", "josh").out().in().where(eq("a"))


Original Traversal
==================
[GraphStep(vertex,[])@[a], VertexStep(OUT,vertex), HasStep([name.eq(josh)]), VertexStep(OUT,vertex), VertexStep(IN,vertex), WherePredicateStep(eq(a))]

Converted Traversal
===================
Neptune steps:
[
    DFEStep(Vertex) {
      DFENode {
        DFEJoinGroupNode[ children={
          DFEPatternNode[(?1, <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>, ?2, <http://aws.amazon.com/neptune/vocab/v01/DefaultNamedGraph>) . project DISTINCT[?1] {rangeCountEstimate=unknown}],
          DFEPatternNode[(?1, ?3, ?4, ?5) . project ALL[?1, ?4] graphFilters=(!= <http://aws.amazon.com/neptune/vocab/v01/DefaultNamedGraph> . ), {rangeCountEstimate=unknown}]
        }, {rangeCountEstimate=unknown}
        ]
      } [Vertex(?1):GraphStep@[a], Vertex(?4):VertexStep]
    } ,
    NeptuneTraverserConverterDFEStep
]
+ not converted into Neptune steps: HasStep([name.eq(josh)]),
Neptune steps:
[
    NeptuneInterleavingStep {
      StepInfo[joinVars=[?7, ?1], frontierElement=Vertex(?7):HasStep, pathElements={a=(last,Vertex(?1):GraphStep@[a])}, listPathElement={}, indexTime=0ms],
      DFEStep(Vertex) {
        DFENode {
          DFEJoinGroupNode[ children={
            DFEPatternNode[(?7, ?8, ?9, ?10) . project ALL[?7, ?9] graphFilters=(!= <http://aws.amazon.com/neptune/vocab/v01/DefaultNamedGraph> . ), {rangeCountEstimate=unknown}],
            DFEPatternNode[(?12, ?11, ?9, ?13) . project ALL[?9, ?12] graphFilters=(!= <http://aws.amazon.com/neptune/vocab/v01/DefaultNamedGraph> . ), {rangeCountEstimate=unknown}]
          }, {rangeCountEstimate=unknown}
          ]
        } [Vertex(?9):VertexStep, Vertex(?12):VertexStep]
      } 
    }
]
+ not converted into Neptune steps: WherePredicateStep(eq(a)),
Neptune steps:
[
    DFECleanupStep
]


Optimized Traversal
===================
Neptune steps:
[
    DFEStep(Vertex) {
      DFENode {
        DFEJoinGroupNode[ children={
          DFEPatternNode[(?1, ?3, ?4, ?5) . project ALL[?1, ?4] graphFilters=(!= defaultGraph[526] . ), {rangeCountEstimate=9223372036854775807}]
        }, {rangeCountEstimate=unknown}
        ]
      } [Vertex(?1):GraphStep@[a], Vertex(?4):VertexStep]
    } ,
    NeptuneTraverserConverterDFEStep
]
+ not converted into Neptune steps: NeptuneHasStep([name.eq(josh)]),
Neptune steps:
[
    NeptuneMemoryTrackerStep,
    NeptuneInterleavingStep {
      StepInfo[joinVars=[?7, ?1], frontierElement=Vertex(?7):HasStep, pathElements={a=(last,Vertex(?1):GraphStep@[a])}, listPathElement={}, indexTime=0ms],
      DFEStep(Vertex) {
        DFENode {
          DFEJoinGroupNode[ children={
            DFEPatternNode[(?7, ?8, ?9, ?10) . project ALL[?7, ?9] graphFilters=(!= defaultGraph[526] . ), {rangeCountEstimate=9223372036854775807}],
            DFEPatternNode[(?12, ?11, ?9, ?13) . project ALL[?9, ?12] graphFilters=(!= defaultGraph[526] . ), {rangeCountEstimate=9223372036854775807}]
          }, {rangeCountEstimate=unknown}
          ]
        } [Vertex(?9):VertexStep, Vertex(?12):VertexStep]
      } 
    }
]
+ not converted into Neptune steps: WherePredicateStep(eq(a)),
Neptune steps:
[
    DFECleanupStep
]


WARNING: >> [NeptuneHasStep([name.eq(josh)]), WherePredicateStep(eq(a))] << (or one of the children for each step) is not supported natively yet

Predicates
==========
# of predicates: 8
```

Lihat [Informasi di `explain`](#gremlin-explain-api-results) untuk deskripsi bagian spesifik DFE dalam laporan.

# API `profile` Gremlin di Neptune
<a name="gremlin-profile-api"></a>

API `profile` Gremlin Neptune menjalankan traversal Gremlin, mengumpulkan berbagai metrik tentang proses, dan menghasilkan laporan profil sebagai output.

Ini berbeda dari TinkerPop langkah.profile () sehingga dapat melaporkan informasi khusus untuk mesin Neptunus.

Laporan profil mencakup informasi berikut tentang rencana kueri:
+ Alur operator fisik
+ Operasi indeks untuk eksekusi dan serialisasi kueri
+ Ukuran hasilnya

API `profile` menggunakan versi diperpanjang dari sintaks HTTP API untuk kueri, dengan `/gremlin/profile` sebagai titik akhir alih-alih `/gremlin`.

## Parameter khusus untuk `profile` Gremlin Neptune
<a name="gremlin-profile-api-parameters"></a>
+ **profile.results** — `boolean`, nilai yang diizinkan: `TRUE` dan `FALSE`, nilai default: `TRUE`.

  Jika true, hasil kueri dikumpulkan dan ditampilkan sebagai bagian dari laporan `profile`. Jika false, hanya jumlah hasil yang ditampilkan.
+ **profile.chop** — `int`, nilai default: 250.

  Jika non-nol, menyebabkan hasil string akan dipotong pada jumlah karakter tersebut. Hal ini tidak menjaga semua hasil dari ditangkap. Ini hanya membatasi ukuran string dalam laporan profil. Jika diatur ke nol, string berisi semua hasil.
+ **profile.serializer** – `string`, nilai default: `<null>`.

  Jika non-null, hasil yang dikumpulkan dikembalikan dalam pesan respons serial dalam format yang ditentukan oleh parameter ini. Jumlah operasi indeks yang diperlukan untuk menghasilkan pesan respons dilaporkan bersama dengan ukuran dalam byte yang akan dikirim ke klien.

  Nilai yang diizinkan adalah `<null>` atau salah satu jenis MIME yang valid atau nilai enum “Serializers” TinkerPop driver.

  ```
  "application/json" or "GRAPHSON"
  "application/vnd.gremlin-v1.0+json" or "GRAPHSON_V1"
  "application/vnd.gremlin-v1.0+json;types=false" or "GRAPHSON_V1_UNTYPED"
  "application/vnd.gremlin-v2.0+json" or "GRAPHSON_V2"
  "application/vnd.gremlin-v2.0+json;types=false" or "GRAPHSON_V2_UNTYPED"
  "application/vnd.gremlin-v3.0+json" or "GRAPHSON_V3"
  "application/vnd.gremlin-v3.0+json;types=false" or "GRAPHSON_V3_UNTYPED"
  "application/vnd.graphbinary-v1.0" or "GRAPHBINARY_V1"
  ```
+ **profile.indexOps** — `boolean`, nilai yang diizinkan: `TRUE` dan `FALSE`, nilai default: `FALSE`.

  Jika true, menunjukkan laporan detail dari semua operasi indeks yang terjadi selama eksekusi dan serialisasi kueri. Peringatan: Laporan ini bisa verbose.



## Contoh output dari `profile` Gremlin Neptune
<a name="gremlin-profile-sample-output"></a>

Berikut ini adalah sampel kueri `profile`.

```
curl -k -X POST https://your-neptune-endpoint:port/gremlin/profile \
     -d '{"gremlin":"g.V().hasLabel(\"airport\").has(\"code\", \"AUS\").emit().repeat(in().simplePath()).times(2).limit(100)", "profile.serializer":"application/vnd.gremlin-v3.0+json"}'
```

Query ini menghasilkan laporan `profile` berikut ketika dieksekusi pada grafik sampel rute udara dari posting blog, [Mari Saya Grafikkan Untuk Anda - Bagian 1 - Rute Udara](https://aws.amazon.com/blogs/database/let-me-graph-that-for-you-part-1-air-routes/).

```
*******************************************************
                Neptune Gremlin Profile
*******************************************************

Query String
==================
g.V().hasLabel("airport").has("code", "AUS").emit().repeat(in().simplePath()).times(2).limit(100)

Original Traversal
==================
[GraphStep(vertex,[]), HasStep([~label.eq(airport), code.eq(AUS)]), RepeatStep(emit(true),[VertexStep(IN,vertex), PathFilterStep(simple), RepeatEndStep],until(loops(2))), RangeGlobalStep(0,100)]

Optimized Traversal
===================
Neptune steps:
[
    NeptuneGraphQueryStep(Vertex) {
        JoinGroupNode {
            PatternNode[(?1, <code>, "AUS", ?) . project ?1 .], {estimatedCardinality=1, indexTime=84, hashJoin=true, joinTime=3, actualTotalOutput=1}
            PatternNode[(?1, <~label>, ?2=<airport>, <~>) . project ask .], {estimatedCardinality=3374, indexTime=29, hashJoin=true, joinTime=0, actualTotalOutput=61}
            RepeatNode {
                Repeat {
                    PatternNode[(?3, ?5, ?1, ?6) . project ?1,?3 . IsEdgeIdFilter(?6) . SimplePathFilter(?1, ?3)) .], {hashJoin=true, estimatedCardinality=50148, indexTime=0, joinTime=3}
                }
                Emit {
                    Filter(true)
                }
                LoopsCondition {
                    LoopsFilter([?1, ?3],eq(2))
                }
            }, annotations={repeatMode=BFS, emitFirst=true, untilFirst=false, leftVar=?1, rightVar=?3}
        }, finishers=[limit(100)], annotations={path=[Vertex(?1):GraphStep, Repeat[Vertex(?3):VertexStep]], joinStats=true, optimizationTime=495, maxVarId=7, executionTime=323}
    },
    NeptuneTraverserConverterStep
]

Physical Pipeline
=================
NeptuneGraphQueryStep
    |-- StartOp
    |-- JoinGroupOp
        |-- SpoolerOp(100)
        |-- DynamicJoinOp(PatternNode[(?1, <code>, "AUS", ?) . project ?1 .], {estimatedCardinality=1, indexTime=84, hashJoin=true})
        |-- SpoolerOp(100)
        |-- DynamicJoinOp(PatternNode[(?1, <~label>, ?2=<airport>, <~>) . project ask .], {estimatedCardinality=3374, indexTime=29, hashJoin=true})
        |-- RepeatOp
            |-- <upstream input> (Iteration 0) [visited=1, output=1 (until=0, emit=1), next=1]
            |-- BindingSetQueue (Iteration 1) [visited=61, output=61 (until=0, emit=61), next=61]
                |-- SpoolerOp(100)
                |-- DynamicJoinOp(PatternNode[(?3, ?5, ?1, ?6) . project ?1,?3 . IsEdgeIdFilter(?6) . SimplePathFilter(?1, ?3)) .], {hashJoin=true, estimatedCardinality=50148, indexTime=0})
            |-- BindingSetQueue (Iteration 2) [visited=38, output=38 (until=38, emit=0), next=0]
                |-- SpoolerOp(100)
                |-- DynamicJoinOp(PatternNode[(?3, ?5, ?1, ?6) . project ?1,?3 . IsEdgeIdFilter(?6) . SimplePathFilter(?1, ?3)) .], {hashJoin=true, estimatedCardinality=50148, indexTime=0})
        |-- LimitOp(100)

Runtime (ms)
============
Query Execution:  392.686
Serialization:   2636.380

Traversal Metrics
=================
Step                                                               Count  Traversers       Time (ms)    % Dur
-------------------------------------------------------------------------------------------------------------
NeptuneGraphQueryStep(Vertex)                                        100         100         314.162    82.78
NeptuneTraverserConverterStep                                        100         100          65.333    17.22
                                            >TOTAL                     -           -         379.495        -

Repeat Metrics
==============
Iteration  Visited   Output    Until     Emit     Next
------------------------------------------------------
        0        1        1        0        1        1
        1       61       61        0       61       61
        2       38       38       38        0        0
------------------------------------------------------
               100      100       38       62       62

Predicates
==========
# of predicates: 16

WARNING: reverse traversal with no edge label(s) - .in() / .both() may impact query performance

Results
=======
Count: 100
Output: [v[3], v[3600], v[3614], v[4], v[5], v[6], v[7], v[8], v[9], v[10], v[11], v[12], v[47], v[49], v[136], v[13], v[15], v[16], v[17], v[18], v[389], v[20], v[21], v[22], v[23], v[24], v[25], v[26], v[27], v[28], v[416], v[29], v[30], v[430], v[31], v[9...
Response serializer: GRYO_V3D0
Response size (bytes): 23566

Index Operations
================
Query execution:
    # of statement index ops: 3
    # of unique statement index ops: 3
    Duplication ratio: 1.0
    # of terms materialized: 0
Serialization:
    # of statement index ops: 200
    # of unique statement index ops: 140
    Duplication ratio: 1.43
    # of terms materialized: 393
```

Selain rencana kueri dikembalikan oleh panggilan ke Neptune `explain`, hasil `profile` menyertakan statistik runtime sekitar eksekusi kueri. Setiap operasi Gabungan ditandai dengan waktu yang dibutuhkan untuk melakukan penggabungannya serta jumlah sebenarnya dari solusi yang melewatinya.

Output `profile` menyertakan waktu yang dibutuhkan selama fase eksekusi kueri inti, serta fase serialisasi jika opsi `profile.serializer` telah ditentukan.

Rincian operasi indeks yang dilakukan selama setiap fase juga disertakan di bagian bawah output `profile`.

Perhatikan bahwa proses berturut-turut dari kueri yang sama dapat menunjukkan hasil yang berbeda dalam hal operasi run-time dan indeks karena caching.

Untuk kueri yang menggunakan langkah `repeat()`, rincian perbatasan pada setiap iterasi tersedia jika langkah `repeat()` didorong ke bawah sebagai bagian dari `NeptuneGraphQueryStep`.

## Perbedaan dalam laporan `profile` saat DFE diaktifkan
<a name="gremlin-profile-dfe-output"></a>

Ketika mesin kueri alternatif Neptune DFE diaktifkan, output `profile` agak berbeda:

**Dioptimalkan oleh Traversal:** Bagian ini serupa dengan yang ada di output `explain`, tetapi berisi informasi tambahan. Ini menyertakan jenis operator DFE yang dipertimbangkan dalam perencanaan, dan kasus terburuk terkait dan perkiraan biaya kasus terbaik.

**Physical Pipeline:** Bagian ini menangkap operator yang digunakan untuk mengeksekusi query. `DFESubQuery`elemen abstrak rencana fisik yang digunakan oleh DFE untuk melaksanakan bagian dari rencana yang menjadi tanggung jawabnya. `DFESubQuery`Elemen-elemen tersebut dibuka di bagian berikut di mana statistik DFE terdaftar.

**DFEQueryStatistik Mesin:** Bagian ini muncul hanya ketika setidaknya sebagian dari kueri dijalankan oleh DFE. Ini menguraikan berbagai statistik runtime yang khusus untuk DFE, dan berisi rincian rinci dari waktu yang dihabiskan di berbagai bagian eksekusi kueri, oleh. `DFESubQuery`

Subquery bersarang dalam `DFESubQuery` elemen yang berbeda diratakan di bagian ini, dan pengidentifikasi unik ditandai dengan header yang dimulai dengan. `subQuery=`

**Metrik Traversal:** Bagian ini menunjukkan metrik traversal tingkat langkah, dan ketika mesin DFE menjalankan semua atau sebagian kueri, menampilkan metrik untuk dan/atau. `DFEStep` `NeptuneInterleavingStep` Lihat [Menyetel kueri Gremlin menggunakan `explain` dan `profile`](gremlin-traversal-tuning.md).

**catatan**  
DFE adalah fitur eksperimental yang dirilis dalam mode lab, format tepat output `profile` dapat berubah.

## Sampel output `profile` ketika Neptune Dataflow engine (DFE) diaktifkan
<a name="gremlin-profile-sample-dfe-output"></a>

Ketika mesin DFE sedang digunakan untuk menjalankan query Gremlin, output dari diformat seperti yang [API `profile` Gremlin](#gremlin-profile-api) ditunjukkan pada contoh di bawah ini.

Kueri:

```
curl https://your-neptune-endpoint:port/gremlin/profile \
  -d "{\"gremlin\": \"g.withSideEffect('Neptune#useDFE', true).V().has('code', 'ATL').out()\"}"
```

```
*******************************************************
                    Neptune Gremlin Profile
    *******************************************************

    Query String
    ==================
    g.withSideEffect('Neptune#useDFE', true).V().has('code', 'ATL').out()

    Original Traversal
    ==================
    [GraphStep(vertex,[]), HasStep([code.eq(ATL)]), VertexStep(OUT,vertex)]

    Optimized Traversal
    ===================
    Neptune steps:
    [
        DFEStep(Vertex) {
          DFENode {
            DFEJoinGroupNode[null](
              children=[
                DFEPatternNode((?1, vp://code[419430926], ?4, defaultGraph[526]) . project DISTINCT[?1] objectFilters=(in(ATL[452987149]) . ), {rangeCountEstimate=1},
                  opInfo=(type=PipelineJoin, cost=(exp=(in=1.00,out=1.00,io=0.00,comp=0.00,mem=0.00),wc=(in=1.00,out=1.00,io=0.00,comp=0.00,mem=0.00)),
                    disc=(type=PipelineScan, cost=(exp=(in=1.00,out=1.00,io=0.00,comp=0.00,mem=34.00),wc=(in=1.00,out=1.00,io=0.00,comp=0.00,mem=34.00))))),
                DFEPatternNode((?1, ?5, ?6, ?7) . project ALL[?1, ?6] graphFilters=(!= defaultGraph[526] . ), {rangeCountEstimate=9223372036854775807})],
              opInfo=[
                OperatorInfoWithAlternative[
                  rec=(type=PipelineJoin, cost=(exp=(in=1.00,out=27.76,io=0.00,comp=0.00,mem=0.00),wc=(in=1.00,out=27.76,io=0.00,comp=0.00,mem=0.00)),
                    disc=(type=PipelineScan, cost=(exp=(in=1.00,out=27.76,io=Infinity,comp=0.00,mem=295147905179352830000.00),wc=(in=1.00,out=27.76,io=Infinity,comp=0.00,mem=295147905179352830000.00)))),
                  alt=(type=PipelineScan, cost=(exp=(in=1.00,out=27.76,io=Infinity,comp=0.00,mem=295147905179352830000.00),wc=(in=1.00,out=27.76,io=Infinity,comp=0.00,mem=295147905179352830000.00)))]])
          } [Vertex(?1):GraphStep, Vertex(?6):VertexStep]
        } ,
        NeptuneTraverserConverterDFEStep,
        DFECleanupStep
    ]


    Physical Pipeline
    =================
    DFEStep
        |-- DFESubQuery1

    DFEQueryEngine Statistics
    =================
    DFESubQuery1
    ╔════╤════════╤════════╤═══════════════════════╤══════════════════════════════════════════════════════════════════════════════════════════════════════════════╤══════╤══════════╤═══════════╤════════╤═══════════╗
    ║ ID │ Out #1 │ Out #2 │ Name                  │ Arguments                                                                                                    │ Mode │ Units In │ Units Out │ Ratio  │ Time (ms) ║
    ╠════╪════════╪════════╪═══════════════════════╪══════════════════════════════════════════════════════════════════════════════════════════════════════════════╪══════╪══════════╪═══════════╪════════╪═══════════╣
    ║ 0  │ 1      │ -      │ DFESolutionInjection  │ solutions=[]                                                                                                 │ -    │ 0        │ 1         │ 0.00   │ 0.01      ║
    ║    │        │        │                       │ outSchema=[]                                                                                                 │      │          │           │        │           ║
    ╟────┼────────┼────────┼───────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼────────┼───────────╢
    ║ 1  │ 2      │ -      │ DFEChunkLocalSubQuery │ subQuery=http://aws.amazon.com/neptune/vocab/v01/dfe/past/graph#089f43e3-4d71-4259-8d19-254ff63cee04/graph_1 │ -    │ 1        │ 1         │ 1.00   │ 0.02      ║
    ╟────┼────────┼────────┼───────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼────────┼───────────╢
    ║ 2  │ 3      │ -      │ DFEChunkLocalSubQuery │ subQuery=http://aws.amazon.com/neptune/vocab/v01/dfe/past/graph#089f43e3-4d71-4259-8d19-254ff63cee04/graph_2 │ -    │ 1        │ 242       │ 242.00 │ 0.02      ║
    ╟────┼────────┼────────┼───────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼────────┼───────────╢
    ║ 3  │ 4      │ -      │ DFEMergeChunks        │ -                                                                                                            │ -    │ 242      │ 242       │ 1.00   │ 0.01      ║
    ╟────┼────────┼────────┼───────────────────────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼────────┼───────────╢
    ║ 4  │ -      │ -      │ DFEDrain              │ -                                                                                                            │ -    │ 242      │ 0         │ 0.00   │ 0.01      ║
    ╚════╧════════╧════════╧═══════════════════════╧══════════════════════════════════════════════════════════════════════════════════════════════════════════════╧══════╧══════════╧═══════════╧════════╧═══════════╝


    subQuery=http://aws.amazon.com/neptune/vocab/v01/dfe/past/graph#089f43e3-4d71-4259-8d19-254ff63cee04/graph_1
    ╔════╤════════╤════════╤══════════════════════╤═════════════════════════════════════════════════════════════╤══════╤══════════╤═══════════╤═══════╤═══════════╗
    ║ ID │ Out #1 │ Out #2 │ Name                 │ Arguments                                                   │ Mode │ Units In │ Units Out │ Ratio │ Time (ms) ║
    ╠════╪════════╪════════╪══════════════════════╪═════════════════════════════════════════════════════════════╪══════╪══════════╪═══════════╪═══════╪═══════════╣
    ║ 0  │ 1      │ -      │ DFEPipelineScan      │ pattern=Node(?1) with property 'code' as ?4 and label 'ALL' │ -    │ 0        │ 1         │ 0.00  │ 0.22      ║
    ║    │        │        │                      │ inlineFilters=[(?4 IN ["ATL"])]                             │      │          │           │       │           ║
    ║    │        │        │                      │ patternEstimate=1                                           │      │          │           │       │           ║
    ╟────┼────────┼────────┼──────────────────────┼─────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
    ║ 1  │ 2      │ -      │ DFEMergeChunks       │ -                                                           │ -    │ 1        │ 1         │ 1.00  │ 0.02      ║
    ╟────┼────────┼────────┼──────────────────────┼─────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
    ║ 2  │ 4      │ -      │ DFERelationalJoin    │ joinVars=[]                                                 │ -    │ 2        │ 1         │ 0.50  │ 0.09      ║
    ╟────┼────────┼────────┼──────────────────────┼─────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
    ║ 3  │ 2      │ -      │ DFESolutionInjection │ solutions=[]                                                │ -    │ 0        │ 1         │ 0.00  │ 0.01      ║
    ║    │        │        │                      │ outSchema=[]                                                │      │          │           │       │           ║
    ╟────┼────────┼────────┼──────────────────────┼─────────────────────────────────────────────────────────────┼──────┼──────────┼───────────┼───────┼───────────╢
    ║ 4  │ -      │ -      │ DFEDrain             │ -                                                           │ -    │ 1        │ 0         │ 0.00  │ 0.01      ║
    ╚════╧════════╧════════╧══════════════════════╧═════════════════════════════════════════════════════════════╧══════╧══════════╧═══════════╧═══════╧═══════════╝


    subQuery=http://aws.amazon.com/neptune/vocab/v01/dfe/past/graph#089f43e3-4d71-4259-8d19-254ff63cee04/graph_2
    ╔════╤════════╤════════╤══════════════════════╤═════════════════════════════════════╤══════╤══════════╤═══════════╤════════╤═══════════╗
    ║ ID │ Out #1 │ Out #2 │ Name                 │ Arguments                           │ Mode │ Units In │ Units Out │ Ratio  │ Time (ms) ║
    ╠════╪════════╪════════╪══════════════════════╪═════════════════════════════════════╪══════╪══════════╪═══════════╪════════╪═══════════╣
    ║ 0  │ 1      │ -      │ DFESolutionInjection │ solutions=[]                        │ -    │ 0        │ 1         │ 0.00   │ 0.01      ║
    ║    │        │        │                      │ outSchema=[?1]                      │      │          │           │        │           ║
    ╟────┼────────┼────────┼──────────────────────┼─────────────────────────────────────┼──────┼──────────┼───────────┼────────┼───────────╢
    ║ 1  │ 2      │ 3      │ DFETee               │ -                                   │ -    │ 1        │ 2         │ 2.00   │ 0.01      ║
    ╟────┼────────┼────────┼──────────────────────┼─────────────────────────────────────┼──────┼──────────┼───────────┼────────┼───────────╢
    ║ 2  │ 4      │ -      │ DFEDistinctColumn    │ column=?1                           │ -    │ 1        │ 1         │ 1.00   │ 0.21      ║
    ║    │        │        │                      │ ordered=false                       │      │          │           │        │           ║
    ╟────┼────────┼────────┼──────────────────────┼─────────────────────────────────────┼──────┼──────────┼───────────┼────────┼───────────╢
    ║ 3  │ 5      │ -      │ DFEHashIndexBuild    │ vars=[?1]                           │ -    │ 1        │ 1         │ 1.00   │ 0.03      ║
    ╟────┼────────┼────────┼──────────────────────┼─────────────────────────────────────┼──────┼──────────┼───────────┼────────┼───────────╢
    ║ 4  │ 5      │ -      │ DFEPipelineJoin      │ pattern=Edge((?1)-[?7:?5]->(?6))    │ -    │ 1        │ 242       │ 242.00 │ 0.51      ║
    ║    │        │        │                      │ constraints=[]                      │      │          │           │        │           ║
    ║    │        │        │                      │ patternEstimate=9223372036854775807 │      │          │           │        │           ║
    ╟────┼────────┼────────┼──────────────────────┼─────────────────────────────────────┼──────┼──────────┼───────────┼────────┼───────────╢
    ║ 5  │ 6      │ 7      │ DFESync              │ -                                   │ -    │ 243      │ 243       │ 1.00   │ 0.02      ║
    ╟────┼────────┼────────┼──────────────────────┼─────────────────────────────────────┼──────┼──────────┼───────────┼────────┼───────────╢
    ║ 6  │ 8      │ -      │ DFEForwardValue      │ -                                   │ -    │ 1        │ 1         │ 1.00   │ 0.01      ║
    ╟────┼────────┼────────┼──────────────────────┼─────────────────────────────────────┼──────┼──────────┼───────────┼────────┼───────────╢
    ║ 7  │ 8      │ -      │ DFEForwardValue      │ -                                   │ -    │ 242      │ 242       │ 1.00   │ 0.02      ║
    ╟────┼────────┼────────┼──────────────────────┼─────────────────────────────────────┼──────┼──────────┼───────────┼────────┼───────────╢
    ║ 8  │ 9      │ -      │ DFEHashIndexJoin     │ -                                   │ -    │ 243      │ 242       │ 1.00   │ 0.31      ║
    ╟────┼────────┼────────┼──────────────────────┼─────────────────────────────────────┼──────┼──────────┼───────────┼────────┼───────────╢
    ║ 9  │ -      │ -      │ DFEDrain             │ -                                   │ -    │ 242      │ 0         │ 0.00   │ 0.01      ║
    ╚════╧════════╧════════╧══════════════════════╧═════════════════════════════════════╧══════╧══════════╧═══════════╧════════╧═══════════╝


    Runtime (ms)
    ============
    Query Execution: 11.744

    Traversal Metrics
    =================
    Step                                                               Count  Traversers       Time (ms)    % Dur
    -------------------------------------------------------------------------------------------------------------
    DFEStep(Vertex)                                                      242         242          10.849    95.48
    NeptuneTraverserConverterDFEStep                                     242         242           0.514     4.52
                                                >TOTAL                     -           -          11.363        -

    Predicates
    ==========
    # of predicates: 18

    Results
    =======
    Count: 242


    Index Operations
    ================
    Query execution:
        # of statement index ops: 0
        # of terms materialized: 0
```

**catatan**  
Karena mesin DFE adalah fitur eksperimental yang dirilis dalam mode lab, format `profile` output yang tepat dapat berubah.

# Menyetel kueri Gremlin menggunakan `explain` dan `profile`
<a name="gremlin-traversal-tuning"></a>

[[Anda sering dapat menyetel kueri Gremlin Anda di Amazon Neptunus untuk mendapatkan kinerja yang lebih baik, menggunakan informasi yang tersedia untuk Anda dalam laporan yang Anda dapatkan dari penjelasan dan profil Neptunus.](gremlin-profile-api.md)](gremlin-explain-api.md) APIs Untuk melakukannya, ia membantu untuk memahami bagaimana Neptune memproses traversals Gremlin.

**penting**  
Perubahan dibuat di TinkerPop versi 3.4.11 yang meningkatkan kebenaran bagaimana kueri diproses, tetapi untuk saat ini terkadang dapat berdampak serius pada kinerja kueri.  
Misalnya, kueri semacam ini dapat berjalan jauh lebih lambat:  

```
g.V().hasLabel('airport').
  order().
    by(out().count(),desc).
  limit(10).
  out()
```
Simpul setelah langkah batas sekarang diambil dengan cara yang tidak optimal karena perubahan 3.4.11. TinkerPop Untuk menghindari hal ini, Anda dapat memodifikasi kueri dengan menambahkan langkah penghalang () kapan saja setelah`order().by()`. Contoh:  

```
g.V().hasLabel('airport').
  order().
    by(out().count(),desc).
  limit(10).
  barrier().
  out()
```
TinkerPop [3.4.11 diaktifkan di mesin Neptunus versi 1.0.5.0.](engine-releases-1.0.5.0.md)

## Memahami pemrosesan traversal Gremlin di Neptune
<a name="gremlin-traversal-processing"></a>

Ketika traversal Gremlin dikirim ke Neptune, ada tiga proses utama yang mengubah traversal menjadi rencana eksekusi yang mendasari untuk dieksekusi mesin. Ketiganya adalah parsing, conversion, dan optimization:

![\[3 proses mengubah kueri Gremlin menjadi rencana eksekusi.\]](http://docs.aws.amazon.com/id_id/neptune/latest/userguide/images/Gremlin_traversal_processing.png)


### Proses penguraian traversal
<a name="gremlin-traversal-processing-parsing"></a>

Langkah pertama dalam memproses traversal adalah mengurainya ke dalam bahasa yang sama. [Di Neptunus, bahasa umum itu adalah serangkaian langkah yang merupakan bagian TinkerPop dari API. TinkerPop](http://tinkerpop.apache.org/javadocs/3.4.8/full/org/apache/tinkerpop/gremlin/process/traversal/Step.html) Masing-masing langkah ini merupakan unit komputasi dalam traversal.

Anda dapat mengirim traversal Gremlin ke Neptune baik sebagai string atau sebagai bytecode. Titik akhir REST dan metode `submit()` driver klien Java mengirim traversals sebagai string, seperti dalam contoh ini:

```
client.submit("g.V()")
```

Driver aplikasi dan bahasa yang menggunakan [Varian bahasa Gremlin (GLV)](https://tinkerpop.apache.org/docs/current/tutorials/gremlin-language-variants/) mengirim traversals dalam bytecode.

### Proses konversi traversal
<a name="gremlin-traversal-processing-conversion"></a>

Langkah kedua dalam memproses traversal adalah mengubah TinkerPop langkah-langkahnya menjadi serangkaian langkah Neptunus yang dikonversi dan tidak dikonversi. Sebagian besar langkah dalam bahasa kueri Apache TinkerPop Gremlin dikonversi ke langkah-langkah khusus Neptunus yang dioptimalkan untuk dijalankan pada mesin Neptunus yang mendasarinya. Ketika sebuah TinkerPop langkah tanpa ekuivalen Neptunus ditemui dalam traversal, langkah itu dan semua langkah selanjutnya dalam traversal diproses oleh mesin kueri. TinkerPop 

Untuk informasi selengkapnya tentang langkah-langkah apa yang dapat dikonversi dalam keadaan apa, lihat [Dukungan langkah Gremlin](gremlin-step-support.md).

### Proses optimasi traversal
<a name="gremlin-traversal-processing-optimization"></a>

Langkah terakhir dalam pemrosesan traversal adalah menjalankan serangkaian langkah dikonversi dan non-dikonversi melalui optimizer, untuk mencoba menentukan rencana eksekusi terbaik. Output dari optimasi ini adalah rencana eksekusi yang diproses mesin Neptune.

## Menggunakan API `explain` Gremlin Neptune untuk menyetel kueri
<a name="gremlin-traversal-tuning-explain"></a>

API explain Neptune tidak sama dengan langkah `explain()` Gremlin. Ia mengembalikan rencana eksekusi akhir yang akan diproses mesin Neptune ketika mengeksekusi kueri. Karena tidak melakukan pemrosesan apa pun, ia mengembalikan rencana yang sama terlepas dari parameter yang digunakan, dan outputnya tidak mengandung statistik tentang eksekusi aktual.

Pertimbangkan traversal sederhana berikut yang menemukan semua vertex bandara untuk Anchorage:

```
g.V().has('code','ANC')
```

Ada dua cara untuk menjalankan traversal ini melalui API `explain` Neptune. Cara pertama adalah untuk membuat panggilan REST ke titik akhir explain, seperti ini:

```
curl -X POST https://your-neptune-endpoint:port/gremlin/explain -d '{"gremlin":"g.V().has('code','ANC')"}'
```

Cara kedua adalah menggunakan workbench cell magic [%%gremlin](notebooks-magics.md#notebooks-cell-magics-gremlin) Neptune dengan parameter `explain`. Ini melewati traversal yang terkandung dalam tubuh sel ke API `explain` Neptune dan kemudian menampilkan output yang dihasilkan ketika Anda menjalankan sel:

```
%%gremlin explain

g.V().has('code','ANC')
```

Output `explain` API yang dihasilkan menjelaskan rencana eksekusi Neptunus untuk traversal. Seperti yang bisa Anda lihat pada gambar di bawah ini, rencananya mencakup masing-masing dari 3 langkah dalam alur pemrosesan:

![\[Output API explain untuk traversal Gremlin sederhana.\]](http://docs.aws.amazon.com/id_id/neptune/latest/userguide/images/Gremlin_explain_output_1.png)


### Penyetelan traversal dengan melihat langkah-langkah yang tidak dikonversi
<a name="gremlin-traversal-tuning-explain-non-converted-steps"></a>

Salah satu hal pertama yang harus dicari di output API `explain` Neptune adalah untuk langkah-langkah Gremlin yang tidak dikonversi ke langkah asli Neptune. Dalam rencana kueri, ketika langkah yang ditemui tidak dapat dikonversi ke langkah asli Neptune, langkah tersebut dan semua langkah berikutnya dalam rencana diproses oleh server Gremlin.

Dalam contoh di atas, semua langkah dalam traversal dikonversi. Mari kita periksa output API `explain` untuk traversal ini:

```
g.V().has('code','ANC').out().choose(hasLabel('airport'), values('code'), constant('Not an airport'))
```

Seperti yang bisa Anda lihat pada gambar di bawah ini, Neptune tidak bisa mengonversi langkah `choose()`:

![\[Output API explain di mana tidak semua langkah dapat dikonversi.\]](http://docs.aws.amazon.com/id_id/neptune/latest/userguide/images/Gremlin_explain_output_2.png)


Ada beberapa hal yang dapat Anda lakukan untuk menyetel performa traversal. Yang pertama adalah menulis ulang sedemikian rupa untuk menghilangkan langkah yang tidak dapat dikonversi. Lainnya adalah memindahkan langkah ke akhir traversal sehingga semua langkah lain dapat dikonversi ke yang asli.

Rencana kueri dengan langkah-langkah yang tidak dikonversi tidak selalu perlu disetel. Jika langkah-langkah yang tidak dapat dikonversi berada di akhir traversal, dan terkait dengan bagaimana output diformat alih-alih bagaimana grafik ditraversalkan, langkah mungkin memiliki sedikit efek pada performa.

### 
<a name="gremlin-traversal-tuning-explain-unindexed-lookups"></a>

Hal lain yang harus dicari ketika memeriksa output dari API `explain` Neptune adalah langkah-langkah yang tidak menggunakan indeks. Traversal berikut menemukan semua bandara dengan penerbangan yang mendarat di Anchorage:

```
g.V().has('code','ANC').in().values('code')
```

Output dari API explain untuk traversal ini adalah:

```
*******************************************************
                Neptune Gremlin Explain
*******************************************************

Query String
============

g.V().has('code','ANC').in().values('code')

Original Traversal
==================
[GraphStep(vertex,[]), HasStep([code.eq(ANC)]), VertexStep(IN,vertex), PropertiesStep([code],value)]

Converted Traversal
===================
Neptune steps:
[
    NeptuneGraphQueryStep(PropertyValue) {
        JoinGroupNode {
            PatternNode[(?1, <~label>, ?2, <~>) . project distinct ?1 .]
            PatternNode[(?1, <code>, "ANC", ?) . project ask .]
            PatternNode[(?3, ?5, ?1, ?6) . project ?1,?3 . IsEdgeIdFilter(?6) .]
            PatternNode[(?3, <~label>, ?4, <~>) . project ask .]
            PatternNode[(?3, ?7, ?8, <~>) . project ?3,?8 . ContainsFilter(?7 in (<code>)) .]
        }, annotations={path=[Vertex(?1):GraphStep, Vertex(?3):VertexStep, PropertyValue(?8):PropertiesStep], maxVarId=9}
    },
    NeptuneTraverserConverterStep
]

Optimized Traversal
===================
Neptune steps:
[
    NeptuneGraphQueryStep(PropertyValue) {
        JoinGroupNode {
            PatternNode[(?1, <code>, "ANC", ?) . project ?1 .], {estimatedCardinality=1}
            PatternNode[(?3, ?5, ?1, ?6) . project ?1,?3 . IsEdgeIdFilter(?6) .], {estimatedCardinality=INFINITY}
            PatternNode[(?3, ?7=<code>, ?8, <~>) . project ?3,?8 .], {estimatedCardinality=7564}
        }, annotations={path=[Vertex(?1):GraphStep, Vertex(?3):VertexStep, PropertyValue(?8):PropertiesStep], maxVarId=9}
    },
    NeptuneTraverserConverterStep
]

Predicates
==========
# of predicates: 26

WARNING: reverse traversal with no edge label(s) - .in() / .both() may impact query performance
```

Pesan `WARNING` di bagian bawah output terjadi karena langkah `in()` dalam traversal tidak dapat ditangani menggunakan salah satu dari 3 indeks yang Neptune pertahankan (lihat [Bagaimana Pernyataan Diindeks di Neptune](feature-overview-storage-indexing.md) dan [Pernyataan Gremlin di Neptune](gremlin-explain-background-statements.md)). Karena langkah `in()` tidak berisi filter edge, langkah itu tidak dapat diselesaikan menggunakan indeks `SPOG`, `POGS` atau `GPSO`. Sebaliknya, Neptune harus melakukan pemindaian serikat untuk menemukan vertex yang diminta, yang jauh lebih efisien.

Ada dua cara untuk menyetel traversal dalam situasi ini. Yang pertama adalah menambahkan satu atau lebih kriteria penyaringan ke langkah `in()` sehingga pencarian yang diindeks dapat digunakan untuk menyelesaikan kueri. Untuk contoh di atas, ini mungkin:

```
g.V().has('code','ANC').in('route').values('code')
```

Output dari API `explain` Neptune untuk traversal yang direvisi tidak lagi berisi pesan `WARNING`:

```
*******************************************************
                Neptune Gremlin Explain
*******************************************************

Query String
============

g.V().has('code','ANC').in('route').values('code')

Original Traversal
==================
[GraphStep(vertex,[]), HasStep([code.eq(ANC)]), VertexStep(IN,[route],vertex), PropertiesStep([code],value)]

Converted Traversal
===================
Neptune steps:
[
    NeptuneGraphQueryStep(PropertyValue) {
        JoinGroupNode {
            PatternNode[(?1, <~label>, ?2, <~>) . project distinct ?1 .]
            PatternNode[(?1, <code>, "ANC", ?) . project ask .]
            PatternNode[(?3, ?5, ?1, ?6) . project ?1,?3 . IsEdgeIdFilter(?6) . ContainsFilter(?5 in (<route>)) .]
            PatternNode[(?3, <~label>, ?4, <~>) . project ask .]
            PatternNode[(?3, ?7, ?8, <~>) . project ?3,?8 . ContainsFilter(?7 in (<code>)) .]
        }, annotations={path=[Vertex(?1):GraphStep, Vertex(?3):VertexStep, PropertyValue(?8):PropertiesStep], maxVarId=9}
    },
    NeptuneTraverserConverterStep
]

Optimized Traversal
===================
Neptune steps:
[
    NeptuneGraphQueryStep(PropertyValue) {
        JoinGroupNode {
            PatternNode[(?1, <code>, "ANC", ?) . project ?1 .], {estimatedCardinality=1}
            PatternNode[(?3, ?5=<route>, ?1, ?6) . project ?1,?3 . IsEdgeIdFilter(?6) .], {estimatedCardinality=32042}
            PatternNode[(?3, ?7=<code>, ?8, <~>) . project ?3,?8 .], {estimatedCardinality=7564}
        }, annotations={path=[Vertex(?1):GraphStep, Vertex(?3):VertexStep, PropertyValue(?8):PropertiesStep], maxVarId=9}
    },
    NeptuneTraverserConverterStep
]

Predicates
==========
# of predicates: 26
```

Pilihan lain jika Anda menjalankan banyak traversals semacam ini adalah untuk menjalankan traversal tersebut dalam sebuah klaster DB Neptune yang memiliki indeks `OSGP` opsional diaktifkan (lihat [Mengaktifkan Indeks OSGP](feature-overview-storage-indexing.md#feature-overview-storage-indexing-osgp)). Mengaktifkan indeks `OSGP` memiliki kelemahan:
+ Indeks ini harus diaktifkan dalam klaster DB sebelum data dimuat.
+ Tingkat penyisipan untuk vertex dan edge dapat melambat hingga 23%.
+ Penggunaan penyimpanan akan meningkat sekitar 20%.
+ Kueri Baca yang menyebarkan permintaan di semua indeks mungkin telah meningkatkan latensi.

Memiliki indeks `OSGP` lebih masuk akal untuk serangkaian pola kueri terbatas, tetapi kecuali jika Anda sering menjalankannya, biasanya lebih baik untuk mencoba untuk memastikan bahwa traversals yang Anda tulis dapat diselesaikan menggunakan tiga indeks utama.

### Menggunakan jumlah besar predikat
<a name="gremlin-traversal-tuning-explain-many-predicates"></a>

Neptune memperlakukan setiap label edge dan setiap nama properti vertex atau edge yang berbeda dalam grafik Anda sebagai predikat, dan dirancang secara default untuk bekerja dengan jumlah predikat berbeda yang relatif rendah. Bila Anda memiliki lebih dari beberapa ribu predikat dalam data grafik Anda, performa dapat menurun.

Output `explain` Neptune akan memperingatkan Anda jika hal ini terjadi:

```
Predicates
==========
# of predicates: 9549
WARNING: high predicate count (# of distinct property names and edge labels)
```

Jika tidak nyaman untuk mengulang pengerjaan model data Anda untuk mengurangi jumlah label dan properti, dan karenanya jumlah predikatnya, cara terbaik untuk menyetel traversal adalah menjalankannya dalam sebuah klaster DB yang memiliki indeks `OSGP` diaktifkan, seperti yang dibahas di atas.

## Menggunakan API `profile` Gremlin Neptune untuk menyetel traversal
<a name="gremlin-traversal-tuning-profile"></a>

API `profile` Neptune sangat berbeda dari langkah `profile()` Gremlin. Seperti halnya API `explain`, outputnya mencakup rencana kueri yang digunakan mesin Neptune saat mengeksekusi traversal. Selain itu, output `profile` menyertakan statistik eksekusi aktual untuk traversal, mengingat bagaimana parameternya ditetapkan.

Sekali lagi, ambil traversal sederhana yang menemukan semua vertex bandara untuk Anchorage:

```
g.V().has('code','ANC')
```

Seperti halnya dengan API `explain`, Anda dapat memanggil API `profile` menggunakan panggilan REST:

```
curl -X POST https://your-neptune-endpoint:port/gremlin/profile -d '{"gremlin":"g.V().has('code','ANC')"}'
```

Anda juga menggunakan workbench cell magic [%%gremlin](notebooks-magics.md#notebooks-cell-magics-gremlin) Neptune dengan parameter `profile`. Ini melewati traversal yang terkandung dalam tubuh sel ke API `profile` Neptune dan kemudian menampilkan output yang dihasilkan ketika Anda menjalankan sel:

```
%%gremlin profile

g.V().has('code','ANC')
```

Output `profile` API yang dihasilkan berisi rencana eksekusi Neptunus untuk traversal dan statistik tentang eksekusi rencana, seperti yang Anda lihat pada gambar ini:

![\[Contoh output API profile Neptune.\]](http://docs.aws.amazon.com/id_id/neptune/latest/userguide/images/Gremlin_profile_output_1.png)


Dalam output `profile`, bagian rencana eksekusi hanya berisi rencana eksekusi akhir untuk traversal, bukan langkah menengahnya. Bagian alur berisi operasi alur fisik yang dilakukan serta waktu aktual (dalam milidetik) yang diperlukan eksekusi traversal. Metrik runtime sangat membantu dalam membandingkan waktu yang diperlukan dua versi traversal yang berbeda saat Anda mengoptimalkan mereka.

**catatan**  
Runtime awal traversal umumnya lebih panjang dari runtime berikutnya, karena yang pertama menyebabkan data yang relevan untuk di-cache.

Bagian ketiga dari output `profile` berisi statistik eksekusi dan hasil traversal. Untuk melihat bagaimana informasi ini dapat berguna dalam menyetel traversal, pertimbangkan traversal berikut, yang menemukan setiap bandara yang namanya dimulai dengan “Anchora”, dan semua bandara yang dapat dijangkau dalam dua hop dari bandara tersebut, mengembalikan kode bandara, rute penerbangan, dan jarak:

```
%%gremlin profile

g.withSideEffect("Neptune#fts.endpoint", "{your-OpenSearch-endpoint-URL").
    V().has("city", "Neptune#fts Anchora~").
    repeat(outE('route').inV().simplePath()).times(2).
    project('Destination', 'Route').
        by('code').
        by(path().by('code').by('dist'))
```

### Metrik traversal di output API `profile` Neptune
<a name="gremlin-traversal-tuning-profile-traversal-metrics"></a>

Set pertama metrik yang tersedia di semua output `profile` adalah metrik traversal. Ini mirip dengan metrik langkah `profile()` Gremlin, dengan beberapa perbedaan:

```
Traversal Metrics
=================
Step                                                               Count  Traversers       Time (ms)    % Dur
-------------------------------------------------------------------------------------------------------------
NeptuneGraphQueryStep(Vertex)                                       3856        3856          91.701     9.09
NeptuneTraverserConverterStep                                       3856        3856          38.787     3.84
ProjectStep([Destination, Route],[value(code), ...                  3856        3856         878.786    87.07
  PathStep([value(code), value(dist)])                              3856        3856         601.359
                                            >TOTAL                     -           -        1009.274        -
```

Kolom pertama dari tabel traversal-metrik mencantumkan langkah-langkah yang dijalankan oleh traversal. Dua langkah pertama umumnya adalah langkah-langkah khusus Neptune, `NeptuneGraphQueryStep` dan `NeptuneTraverserConverterStep`.

`NeptuneGraphQueryStep` mewakili waktu eksekusi untuk seluruh bagian dari traversal yang dapat dikonversi dan dieksekusi secara native oleh mesin Neptune.

`NeptuneTraverserConverterStep`mewakili proses mengubah output dari langkah-langkah yang dikonversi tersebut menjadi TinkerPop traversers yang memungkinkan langkah-langkah yang tidak dapat dikonversi langkah-langkah, jika ada, untuk diproses, atau untuk mengembalikan hasil dalam format -kompatibel. TinkerPop

Pada contoh di atas, kita memiliki beberapa langkah yang tidak dikonversi, jadi kita melihat bahwa masing-masing TinkerPop langkah ini (`ProjectStep`,`PathStep`) kemudian muncul sebagai baris dalam tabel.

[Kolom kedua dalam tabel`Count`,, melaporkan jumlah pelintas yang *diwakili* yang melewati langkah, sedangkan kolom ketiga,`Traversers`, melaporkan jumlah pelintas yang melewati langkah itu, seperti yang dijelaskan dalam dokumentasi langkah profil. TinkerPop](https://tinkerpop.apache.org/docs/current/reference/#profile-step)

Dalam contoh kita ada 3.856 simpul dan 3.856 traversers dikembalikan oleh`NeptuneGraphQueryStep`, dan angka-angka ini tetap sama sepanjang pengolahan yang tersisa karena`ProjectStep`dan`PathStep`memformat hasil, tidak menyaring mereka.

**catatan**  
Tidak seperti TinkerPop, mesin Neptunus tidak mengoptimalkan kinerja *dengan* menumpuk di langkah-langkahnya. `NeptuneGraphQueryStep` `NeptuneTraverserConverterStep` Bulking adalah TinkerPop operasi yang menggabungkan pelintas pada simpul yang sama untuk mengurangi overhead operasional, dan itulah yang menyebabkan dan angka berbeda. `Count` `Traversers` Karena bulking hanya terjadi pada langkah-langkah yang didelegasikan Neptunus, dan bukan pada langkah-langkah yang TinkerPop ditangani Neptunus secara asli, kolom dan kolom jarang berbeda. `Count` `Traverser`

Kolom Waktu melaporkan jumlah milidetik yang diambil langkah, dan kolom `% Dur` melaporkan berapa persen dari total waktu pemrosesan yang diambil langkah. Ini adalah metrik yang memberi tahu Anda tempat untuk memfokuskan upaya penyetelan dengan menunjukkan langkah-langkah yang memakan waktu paling lama.

### Metrik operasi indeks di output API `profile` Neptune
<a name="gremlin-traversal-tuning-profile-index-operations"></a>

Satu set metrik dalam output dari API profil Neptune adalah operasi indeks:

```
Index Operations
================
Query execution:
    # of statement index ops: 23191
    # of unique statement index ops: 5960
    Duplication ratio: 3.89
    # of terms materialized: 0
```

Laporan ini:
+ Jumlah total pencarian indeks.
+ Jumlah pencarian indeks unik yang dilakukan.
+ Rasio total pencarian indeks ke yang unik. Rasio yang lebih rendah menunjukkan redundansi yang lebih sedikit.
+ Jumlah istilah terwujud dari kamus istilah.

### Metrik repeat di output API `profile` Neptune
<a name="gremlin-traversal-tuning-profile-repeat-metrics"></a>

Jika traversal Anda menggunakan `repeat()` seperti pada contoh di atas, maka bagian yang berisi metrik repeat muncul di output `profile`:

```
Repeat Metrics
==============
Iteration  Visited   Output    Until     Emit     Next
------------------------------------------------------
        0        2        0        0        0        2
        1       53        0        0        0       53
        2     3856     3856     3856        0        0
------------------------------------------------------
              3911     3856     3856        0       55
```

Laporan ini:
+ Jumlah loop untuk satu baris (kolom `Iteration`).
+ Jumlah elemen yang dikunjungi oleh loop (kolom `Visited`).
+ Jumlah elemen yang dioutput oleh loop (kolom `Output`).
+ Elemen terakhir yang dioutput oleh loop (kolom `Until`).
+ Jumlah elemen yang dikeluarkan oleh loop (kolom `Emit`).
+ Jumlah elemen yang dilewatkan dari loop ke loop berikutnya (kolom `Next`).

Metrik repeat ini sangat membantu dalam memahami faktor percabangan traversal Anda, untuk mendapatkan kesan berapa banyak pekerjaan yang sedang dilakukan oleh database. Anda dapat menggunakan angka-angka ini untuk mendiagnosis masalah performa, terutama ketika traversal yang sama berkinerja berbeda secara dramatis dengan parameter lainnya.

### Metrik pencarian teks lengkap di output API `profile` Neptune
<a name="gremlin-traversal-tuning-profile-fts-metrics"></a>

Ketika sebuah traversal menggunakan [pencarian teks penuh](full-text-search.md) seperti dalam contoh di atas, maka bagian yang berisi metrik pencarian teks lengkap (FTS) muncul di output `profile`:

```
FTS Metrics
==============
SearchNode[(idVar=?1, query=Anchora~, field=city) . project ?1 .],
    {endpoint=your-OpenSearch-endpoint-URL, incomingSolutionsThreshold=1000, estimatedCardinality=INFINITY,
    remoteCallTimeSummary=[total=65, avg=32.500000, max=37, min=28],
    remoteCallTime=65, remoteCalls=2, joinTime=0, indexTime=0, remoteResults=2}

    2 result(s) produced from SearchNode above
```

Ini menunjukkan kueri yang dikirim ke klaster ElasticSearch (ES) dan melaporkan beberapa metrik tentang interaksi yang dapat membantu Anda menentukan masalah kinerja ElasticSearch yang berkaitan dengan penelusuran teks lengkap:
+ Ringkasan informasi tentang panggilan ke ElasticSearch indeks:
  + Jumlah total milidetik yang dibutuhkan oleh semua remoteCalls untuk memenuhi kueri (`total`).
  + Jumlah rata-rata milidetik yang dihabiskan di remoteCall (`avg`).
  + Jumlah minimum milidetik yang dihabiskan di remoteCall (`min`).
  + Jumlah maksimum milidetik yang dihabiskan di remoteCall (`max`).
+ Total waktu yang dikonsumsi oleh RemoteCalls to ElasticSearch ()`remoteCallTime`.
+ Jumlah RemoteCalls dibuat untuk ElasticSearch ()`remoteCalls`.
+ Jumlah milidetik yang dihabiskan dalam gabungan ElasticSearch hasil ()`joinTime`.
+ Jumlah milidetik yang dihabiskan dalam pencarian indeks (`indexTime`).
+ Jumlah total hasil yang dikembalikan oleh ElasticSearch (`remoteResults`).

# Dukungan langkah Gremlin asli di Amazon Neptune
<a name="gremlin-step-support"></a>

Mesin Amazon Neptune saat ini tidak memiliki dukungan asli penuh untuk semua langkah Gremlin, seperti yang dijelaskan di [Menyetel kueri Gremlin](gremlin-traversal-tuning.md). Dukungan saat ini terbagi dalam empat kategori:
+ [Langkah-langkah Gremlin yang selalu dapat dikonversi ke operasi mesin Neptune asli](#gremlin-steps-always)
+ [Langkah Gremlin yang dapat dikonversi ke operasi mesin Neptune asli dalam beberapa kasus](#gremlin-steps-sometimes) 
+ [Langkah Gremlin yang tidak pernah dikonversi ke operasi mesin Neptune asli](#gremlin-steps-never) 
+ [Langkah-langkah Gremlin yang tidak didukung di Neptune sama sekali](#neptune-gremlin-steps-unsupported) 

## Langkah-langkah Gremlin yang selalu dapat dikonversi ke operasi mesin Neptune asli
<a name="gremlin-steps-always"></a>

Banyak langkah Gremlin dapat dikonversi ke operasi mesin Neptune asli selama mereka memenuhi kondisi berikut:
+ Mereka tidak didahului di dalam kueri dengan langkah yang tidak dapat dikonversi.
+ Langkah induk mereka, jika ada, dapat dikonversi,
+ Semua traversals turunan mereka, jika ada, dapat dikonversi.

Langkah-langkah Gremlin berikut selalu dikonversi ke operasi mesin Neptune asli jika mereka memenuhi kondisi tersebut:
+ [dan](http://tinkerpop.apache.org/docs/current/reference/#and-step)
+ [sebagai ()](http://tinkerpop.apache.org/docs/current/reference/#as-step)
+ [menghitung ()](http://tinkerpop.apache.org/docs/current/reference/#count-step)
+ [E ()](http://tinkerpop.apache.org/docs/current/reference/#graph-step)
+ [memancarkan ()](http://tinkerpop.apache.org/docs/current/reference/#emit-step)
+ [menjelaskan ()](http://tinkerpop.apache.org/docs/current/reference/#explain-step)
+ [kelompok ()](http://tinkerpop.apache.org/docs/current/reference/#group-step)
+ [GroupCount ()](http://tinkerpop.apache.org/docs/current/reference/#groupcount-step)
+ [identitas ()](http://tinkerpop.apache.org/docs/current/reference/#identity-step)
+ [adalah](http://tinkerpop.apache.org/docs/current/reference/#is-step)
+ [kunci ()](http://tinkerpop.apache.org/docs/current/reference/#key-step)
+ [label ()](http://tinkerpop.apache.org/docs/current/reference/#label-step)
+ [batas ()](http://tinkerpop.apache.org/docs/current/reference/#limit-step)
+ [lokal ()](http://tinkerpop.apache.org/docs/current/reference/#local-step)
+ [loop ()](http://tinkerpop.apache.org/docs/current/reference/#loops-step)
+ [tidak ()](http://tinkerpop.apache.org/docs/current/reference/#not-step)
+ [atau ()](http://tinkerpop.apache.org/docs/current/reference/#or-step)
+ [profil ()](http://tinkerpop.apache.org/docs/current/reference/#profile-step)
+ [properti ()](http://tinkerpop.apache.org/docs/current/reference/#properties-step)
+ [subgraf ()](http://tinkerpop.apache.org/docs/current/reference/#subgraph-step)
+ [sampai ()](http://tinkerpop.apache.org/docs/current/reference/#until-step)
+ [V ()](http://tinkerpop.apache.org/docs/current/reference/#graph-step)
+ [nilai ()](http://tinkerpop.apache.org/docs/current/reference/#value-step)
+ [ValueMap ()](http://tinkerpop.apache.org/docs/current/reference/#valuemap-step)
+ [nilai ()](http://tinkerpop.apache.org/docs/current/reference/#values-step)

## Langkah Gremlin yang dapat dikonversi ke operasi mesin Neptune asli dalam beberapa kasus
<a name="gremlin-steps-sometimes"></a>

Beberapa langkah Gremlin dapat dikonversi ke operasi mesin Neptune asli dalam beberapa situasi tetapi tidak pada situasi lain:
+ [addE( )](http://tinkerpop.apache.org/docs/current/reference/#addedge-step) — Langkah `addE()` umumnya dapat dikonversi ke operasi mesin Neptune asli, kecuali segera diikuti oleh langkah `property()` yang berisi traversal sebagai kunci.
+ [addV( )](http://tinkerpop.apache.org/docs/current/reference/#addvertex-step) — Langkah `addV()` umumnya dapat dikonversi ke operasi mesin Neptune asli, kecuali segera diikuti oleh langkah `property()` yang berisi traversal sebagai kunci, atau kecuali beberapa label ditetapkan.
+ [aggregate( )](http://tinkerpop.apache.org/docs/current/reference/#store-step) — Langkah `aggregate()` umumnya dapat dikonversi ke operasi mesin Neptune asli, kecuali langkah ini digunakan dalam traversal turunan atau sub-traversal, atau kecuali nilai yang disimpan adalah sesuatu selain vertex, edge, id, label atau nilai properti.

  Dalam contoh di bawah ini, `aggregate()` tidak dikonversi karena sedang digunakan dalam traversal turunan:

  ```
  g.V().has('code','ANC').as('a')
       .project('flights').by(select('a')
       .outE().aggregate('x'))
  ```

  Dalam contoh ini, aggregate( ) tidak dikonversi karena yang disimpan adalah `min()` dari nilai:

  ```
  g.V().has('code','ANC').outE().aggregate('x').by(values('dist').min())
  ```
+ [barrier( )](http://tinkerpop.apache.org/docs/current/reference/#barrier-step) — Langkah `barrier()` umumnya dapat dikonversi ke operasi mesin Neptune asli, kecuali langkah yang mengikutinya tidak dikonversi.
+ [cap( )](http://tinkerpop.apache.org/docs/current/reference/#cap-step) — Satu-satunya kasus di mana langkah `cap()` dikonversi adalah ketika dikombinasikan dengan langkah `unfold()` untuk mengembalikan versi tidak dilipat dari agregat vertex, edge, id, atau nilai poperti. Dalam contoh ini, `cap()` akan dikonversi karena diikuti oleh `.unfold()`:

  ```
  g.V().has('airport','country','IE').aggregate('airport').limit(2)
       .cap('airport').unfold()
  ```

  Namun, jika Anda menghapus `.unfold()`, `cap()` tidak akan dikonversi:

  ```
  g.V().has('airport','country','IE').aggregate('airport').limit(2)
       .cap('airport')
  ```
+ [coalesce ()](http://tinkerpop.apache.org/docs/current/reference/#coalesce-step) [— Satu-satunya kasus di mana `coalesce()` langkah dikonversi adalah ketika mengikuti [pola Upsert](http://tinkerpop.apache.org/docs/current/recipes/#element-existence) yang direkomendasikan pada halaman resep. TinkerPop ](http://tinkerpop.apache.org/docs/current/recipes/) Pola coalesce( ) lainnya tidak diperbolehkan. Konversi terbatas pada kasus di mana semua traversals turunan dapat dikonversi, mereka semua menghasilkan jenis yang sama sebagai output (vertex, edge, id, nilai, kunci, atau label), mereka semua melakukan traversal ke elemen baru, dan mereka tidak mengandung langkah `repeat()`.
+ [constant( )](http://tinkerpop.apache.org/docs/current/reference/#constant-step) — Langkah constant( ) saat ini hanya dikonversi jika digunakan dalam bagian `sack().by()` dari traversal untuk menetapkan nilai konstan, seperti ini:

  ```
  g.V().has('code','ANC').sack(assign).by(constant(10)).out().limit(2)
  ```
+ [cyclicPath( )](http://tinkerpop.apache.org/docs/current/reference/#cyclicpath-step) — Langkah `cyclicPath()` umumnya dapat dikonversi ke operasi mesin Neptune asli, kecuali langkah ini digunakan dengan modulator `by()`, `from()`, atau `to()`. Dalam kueri berikut, misalnya, `cyclicPath()` tidak dikonversi:

  ```
  g.V().has('code','ANC').as('a').out().out().cyclicPath().by('code')
  g.V().has('code','ANC').as('a').out().out().cyclicPath().from('a')
  g.V().has('code','ANC').as('a').out().out().cyclicPath().to('a')
  ```
+ [drop( )](http://tinkerpop.apache.org/docs/current/reference/#drop-step) — Langkah `drop()` umumnya dapat dikonversi ke operasi mesin Neptune asli, kecuali langkah ini digunakan di dalam langkah `sideEffect(` atau `optional()`.
+ [fold ()](http://tinkerpop.apache.org/docs/current/reference/#fold-step) — Hanya ada dua situasi di mana langkah fold () dapat dikonversi, yaitu ketika digunakan dalam [pola Upsert](http://tinkerpop.apache.org/docs/current/recipes/#element-existence) yang direkomendasikan pada [halaman TinkerPop resep](http://tinkerpop.apache.org/docs/current/recipes/), dan ketika digunakan dalam `group().by()` konteks seperti ini:

  ```
  g.V().has('code','ANC').out().group().by().by(values('code', 'city').fold())
  ```
+  [has ()](http://tinkerpop.apache.org/docs/current/reference/#has-step) — Langkah `has () `umumnya dapat dikonversi ke operasi mesin Neptunus asli yang disediakan kueri dengan `T` menggunakan predikat `P.eq`, `P.neq` atau `P.contains`. Harapkan variasi `has () `yang menyiratkan contoh `P` untuk dikonversi ke native juga, seperti `HasiD ('id1234')` yang setara dengan `has (eq, t.id, 'id1234') `. 
+ [id( )](http://tinkerpop.apache.org/docs/current/reference/#id-step) — Langkah `id()` dikonversi kecuali digunakan pada properti, seperti ini:

  ```
  g.V().has('code','ANC').properties('code').id()
  ```
+  [Mergee ()](https://tinkerpop.apache.org/docs/current/reference/#mergeedge-step) — `mergeE()` Langkah dapat dikonversi ke operasi mesin Neptunus asli jika parameter (kondisi gabungan, `onCreate` dan`onMatch`) konstan (baik, konstanta`null`, atau a). `Map` `select()` `Map` Semua contoh di [tepi atas](https://docs.aws.amazon.com//neptune/latest/userguide/gremlin-efficient-upserts.html#gremlin-upserts-edges) dapat dikonversi. 
+  [MergeV ()](https://tinkerpop.apache.org/docs/current/reference/#mergevertex-step) — Langkah mergeV () dapat dikonversi ke operasi mesin Neptunus asli jika parameter (kondisi gabungan, `onCreate` dan`onMatch`) konstan (baik, konstanta, atau `null` a). `Map` `select()` `Map` Semua contoh dalam [simpul upserting dapat dikonversi.](https://docs.aws.amazon.com//neptune/latest/userguide/gremlin-efficient-upserts.html#gremlin-upserts-vertices) 
+ [order( )](http://tinkerpop.apache.org/docs/current/reference/#order-step) — Langkah `order()` umumnya dapat dikonversi ke operasi mesin Neptune asli, kecuali langkah yang mengikutinya adalah true:
  + Langkah `order()` berada dalam traversal turunan nested, seperti ini:

    ```
    g.V().has('code','ANC').where(V().out().order().by(id))
    ```
  + Pengurutan lokal sedang digunakan, seperti misalnya dengan `order(local)`.
  + Sebuah pembanding kustom sedang digunakan dalam modulasi `by()` untuk mengurutkan. Contohnya adalah penggunaan `sack()` ini:

    ```
    g.withSack(0).
      V().has('code','ANC').
          repeat(outE().sack(sum).by('dist').inV()).times(2).limit(10).
          order().by(sack())
    ```
  + Ada beberapa pengurutan pada elemen yang sama.
+ [project( )](http://tinkerpop.apache.org/docs/current/reference/#project-step) — Langkah `project()` umumnya dapat dikonversi ke operasi mesin Neptune asli, kecuali jumlah pernyataan `by()` yang mengikuti `project()` tidak cocok dengan jumlah label yang ditentukan, seperti di sini:

  ```
  g.V().has('code','ANC').project('x', 'y').by(id)
  ```
+ [range( )](http://tinkerpop.apache.org/docs/current/reference/#range-step) — Langkah `range()` hanya dikonversi ketika ujung bawah rentang yang dimaksud adalah nol (misalnya, `range(0,3)`).
+ [repeat( )](http://tinkerpop.apache.org/docs/current/reference/#repeat-step) — Langkah `repeat()` umumnya dapat dikonversi ke operasi mesin Neptune asli, kecuali di-nested di dalam langkah `repeat()` lain, seperti ini:

  ```
  g.V().has('code','ANC').repeat(out().repeat(out()).times(2)).times(2)
  ```
+ [sack( )](http://tinkerpop.apache.org/docs/current/reference/#sack-step) — Langkah `sack()` umumnya dapat dikonversi ke operasi mesin Neptune asli, kecuali dalam kasus berikut:
  + Jika operator sack non-numerik sedang digunakan.
  + Jika operator sack numerik selain `+`, `-`, `mult`, `div`, `min` dan `max` sedang digunakan.
  + Jika `sack()` digunakan di dalam langkah `where()` untuk menyaring berdasarkan nilai sack, seperti di sini:

    ```
    g.V().has('code','ANC').sack(assign).by(values('code')).where(sack().is('ANC'))
    ```
+ [sum( )](http://tinkerpop.apache.org/docs/current/reference/#sum-step) — Langkah `sum()` umumnya dapat dikonversi ke operasi mesin Neptune asli, tetapi tidak ketika digunakan untuk menghitung penjumlahan global, seperti ini:

  ```
  g.V().has('code','ANC').outE('routes').values('dist').sum()
  ```
+ [union ()](http://tinkerpop.apache.org/docs/current/reference/#union-step) — `union()` Langkah ini dapat dikonversi ke operasi mesin Neptunus asli selama itu adalah langkah terakhir dalam kueri selain dari langkah terminal.
+ [unfold ()](http://tinkerpop.apache.org/docs/current/reference/#unfold-step) — `unfold()` Langkah ini hanya dapat dikonversi ke operasi mesin Neptunus asli ketika digunakan dalam pola [Upsert yang](http://tinkerpop.apache.org/docs/current/recipes/#element-existence) direkomendasikan pada TinkerPop halaman [resep](http://tinkerpop.apache.org/docs/current/recipes/), dan ketika digunakan bersama dengan seperti ini: `cap()`

  ```
  g.V().has('airport','country','IE').aggregate('airport').limit(2)
       .cap('airport').unfold()
  ```
+ [where( )](http://tinkerpop.apache.org/docs/current/reference/#where-step) — Langkah `where()` umumnya dapat dikonversi ke operasi mesin Neptune asli, kecuali dalam kasus berikut:
  + Saat modulasi by( ) digunakan, seperti ini:

    ```
    g.V().hasLabel('airport').as('a')
         .where(gt('a')).by('runways')
    ```
  + Ketika operator perbandingan selain `eq`, `neq`, `within`, dan `without` digunakan.
  + Ketika agregasi yang disediakan pengguna digunakan.

## Langkah Gremlin yang tidak pernah dikonversi ke operasi mesin Neptune asli
<a name="gremlin-steps-never"></a>

Langkah-langkah Gremlin berikut didukung di Neptune tetapi tidak pernah dikonversi ke operasi mesin Neptune asli. Sebaliknya, mereka dieksekusi oleh server Gremlin.
+ [pilih ()](http://tinkerpop.apache.org/docs/current/reference/#choose-step)
+ [koin ()](http://tinkerpop.apache.org/docs/current/reference/#coin-step)
+ [menyuntikkan ()](http://tinkerpop.apache.org/docs/current/reference/#inject-step)
+ [cocok ()](http://tinkerpop.apache.org/docs/current/reference/#match-step)
+ [matematika ()](http://tinkerpop.apache.org/docs/current/reference/#math-step)
+ [maks ()](http://tinkerpop.apache.org/docs/current/reference/#max-step)
+ [berarti ()](http://tinkerpop.apache.org/docs/current/reference/#mean-step)
+ [min ()](http://tinkerpop.apache.org/docs/current/reference/#min-step)
+ [pilihan ()](http://tinkerpop.apache.org/docs/current/reference/#option-step)
+ [opsional ()](http://tinkerpop.apache.org/docs/current/reference/#optional-step)
+ [jalan ()](http://tinkerpop.apache.org/docs/current/reference/#path-step)
+ [PropertyMap ()](http://tinkerpop.apache.org/docs/current/reference/#propertymap-step)
+ [sampel ()](http://tinkerpop.apache.org/docs/current/reference/#sample-step)
+ [lewati ()](http://tinkerpop.apache.org/docs/current/reference/#skip-step)
+ [ekor ()](http://tinkerpop.apache.org/docs/current/reference/#tail-step)
+ [TimeLimit ()](http://tinkerpop.apache.org/docs/current/reference/#timelimit-step)
+ [pohon ()](http://tinkerpop.apache.org/docs/current/reference/#tree-step)

## Langkah-langkah Gremlin yang tidak didukung di Neptune sama sekali
<a name="neptune-gremlin-steps-unsupported"></a>

Langkah-langkah Gremlin berikut tidak didukung sama sekali di Neptune. Dalam kebanyakan kasus ini karena mereka memerlukan `GraphComputer`, yang saat ini tidak didukung Neptune.
+ [ConnectedComponent ()](http://tinkerpop.apache.org/docs/current/reference/#connectedcomponent-step)
+ [io ()](http://tinkerpop.apache.org/docs/current/reference/#io-step)
+ [ShortestPath ()](http://tinkerpop.apache.org/docs/current/reference/#shortestpath-step)
+ [denganKomputer ()](http://tinkerpop.apache.org/docs/current/reference/#with-step)
+ [PageRank ()](http://tinkerpop.apache.org/docs/current/reference/#pagerank-step)
+ [PeerPressure ()](http://tinkerpop.apache.org/docs/current/reference/#peerpressure-step)
+ [program ()](http://tinkerpop.apache.org/docs/current/reference/#program-step)

`io()`Langkah ini sebenarnya sebagian didukung, karena dapat digunakan untuk `read()` dari URL tetapi tidak untuk`write()`.

# Menggunakan Gremlin dengan mesin kueri Neptunus DFE
<a name="gremlin-with-dfe"></a>

Jika Anda mengaktifkan [mesin kueri alternatif](neptune-dfe-engine.md) Neptunus yang dikenal sebagai DFE dalam [mode lab](features-lab-mode.md) (dengan menyetel parameter cluster `neptune_lab_mode` DB ke)`DFEQueryEngine=enabled`, maka Neptunus menerjemahkan Gremlin hanya-baca queries/traversals menjadi representasi logis perantara dan menjalankannya pada mesin DFE bila memungkinkan.

Namun, DFE belum mendukung semua langkah Gremlin. Ketika sebuah langkah tidak dapat dijalankan secara asli di DFE, Neptunus kembali menjalankan langkahnya. TinkerPop `profile`Laporan `explain` dan termasuk peringatan ketika ini terjadi.

# Cakupan langkah Gremlin di DFE
<a name="gremlin-step-coverage-in-DFE"></a>

 Gremlin DFE adalah fitur labmode dan dapat digunakan dengan mengaktifkan parameter cluster atau menggunakan petunjuk kueri. `Neptune#useDFE` Untuk informasi lebih lanjut, silakan merujuk ke [Menggunakan Gremlin dengan mesin kueri Neptunus DFE](https://docs.aws.amazon.com//neptune/latest/userguide/gremlin-with-dfe.html). 

 Langkah-langkah berikut tersedia untuk digunakan di Gremlin DFE. 

## Langkah-langkah jalur dan traversal:
<a name="DFE-path-and-traversal"></a>

 [asDate ()](https://tinkerpop.apache.org/docs/current/reference/#asDate-step) [https://tinkerpop.apache.org/docs/current/reference/#order-step](https://tinkerpop.apache.org/docs/current/reference/#order-step) [project ()](https://tinkerpop.apache.org/docs/current/reference/#project-step)[, [range ()](https://tinkerpop.apache.org/docs/current/reference/#range-step), [repeat ()](https://tinkerpop.apache.org/docs/current/reference/#repeat-step), [reverse ()](https://tinkerpop.apache.org/docs/current/reference/#reverse-step), [sack (), sample ()](https://tinkerpop.apache.org/docs/current/reference/#sack-step)[, [select ()](https://tinkerpop.apache.org/docs/current/reference/#select-step)](https://tinkerpop.apache.org/docs/current/reference/#sample-step), [sideEffect ()](https://tinkerpop.apache.org/docs/current/reference/#sideeffect-step), [split ()](https://tinkerpop.apache.org/docs/current/reference/#split-step), [unfold (), union ()](https://tinkerpop.apache.org/docs/current/reference/#unfold-step)](https://tinkerpop.apache.org/docs/current/reference/#union-step) 

## Langkah-langkah agregat dan pengumpulan:
<a name="DFE-aggregate-and-collection"></a>

 [agregat (global)](https://tinkerpop.apache.org/docs/current/reference/#aggregate-step), [gabungkan ()](https://tinkerpop.apache.org/docs/current/reference/#combine-step), [hitung ()](https://tinkerpop.apache.org/docs/current/reference/#count-step), [dedup ()](https://tinkerpop.apache.org/docs/current/reference/#dedup-step), [dedup (lokal), lipat ()](https://tinkerpop.apache.org/docs/current/reference/#dedup-step)[, grup ()](https://tinkerpop.apache.org/docs/current/reference/#fold-step)[, [groupCount](https://tinkerpop.apache.org/docs/current/reference/#groupcount-step) ()](https://tinkerpop.apache.org/docs/current/reference/#group-step), 

## Langkah-langkah matematika:
<a name="DFE-mathematical"></a>

 [max ()](https://tinkerpop.apache.org/docs/current/reference/#max-step), [mean ()](https://tinkerpop.apache.org/docs/current/reference/#mean-step), [min ()](https://tinkerpop.apache.org/docs/current/reference/#min-step), [sum ()](https://tinkerpop.apache.org/docs/current/reference/#sum-step) 

## Langkah-langkah elemen:
<a name="DFE-element"></a>

 [otherV ()](https://tinkerpop.apache.org/docs/current/reference/#otherv-step), [elementMap (), elemen ()](https://tinkerpop.apache.org/docs/current/reference/#elementmap-step)[, v ()](https://tinkerpop.apache.org/docs/current/reference/#element-step)[, out ()](https://tinkerpop.apache.org/docs/current/reference/#graph-step)[, in (), keduanya (), oute (), inE (), boThe (), outV (), inV (), bothV (), otherV ()](https://tinkerpop.apache.org/docs/current/reference/#vertex-step) 

## Langkah-langkah properti:
<a name="DFE-property"></a>

 [properti ()](https://tinkerpop.apache.org/docs/current/reference/#properties-step), [key ()](https://tinkerpop.apache.org/docs/current/reference/#key-step), [valueMap ()](https://tinkerpop.apache.org/docs/current/reference/#propertymap-step), [value](https://tinkerpop.apache.org/docs/current/reference/#value-step) () 

## Langkah-langkah filter:
<a name="DFE-filter"></a>

 [dan ()](https://tinkerpop.apache.org/docs/current/reference/#and-step)[, [coalesce ()](https://tinkerpop.apache.org/docs/current/reference/#coalesce-step), [coin ()](https://tinkerpop.apache.org/docs/current/reference/#coin-step), [has ()](https://tinkerpop.apache.org/docs/current/reference/#has-step), [is ()](https://tinkerpop.apache.org/docs/current/reference/#is-step), [local (), none ()](https://tinkerpop.apache.org/docs/current/reference/#local-step)[, not ()](https://tinkerpop.apache.org/docs/current/reference/#none-step)[, or ()](https://tinkerpop.apache.org/docs/current/reference/#not-step)[, where ()](https://tinkerpop.apache.org/docs/current/reference/#or-step)](https://tinkerpop.apache.org/docs/current/reference/#where-step) 

## Langkah-langkah manipulasi string:
<a name="DFE-string-manipulation"></a>

 [concat ()](https://tinkerpop.apache.org/docs/current/reference/#concat-step)[, [lTrim ()](https://tinkerpop.apache.org/docs/current/reference/#lTrim-step), [rTrim (), substring ()](https://tinkerpop.apache.org/docs/current/reference/#rtrim-step)[, toLower (),](https://tinkerpop.apache.org/docs/current/reference/#substring-step)[[toupper](https://tinkerpop.apache.org/docs/current/reference/#toUpper-step) ()](https://tinkerpop.apache.org/docs/current/reference/#toLower-step), trim ()](https://tinkerpop.apache.org/docs/current/reference/#trim-step) 

## Predikat:
<a name="DFE-predicates"></a>
+  [Bandingkan: eq, neq, lt, lte, gt, gte](https://tinkerpop.apache.org/docs/current/reference/#a-note-on-predicates) 
+  [Berisi: di dalam, tanpa](https://tinkerpop.apache.org/docs/current/reference/#a-note-on-predicates) 
+  [TextP: EndingWith, berisi,,, NotContaining notStartingWith notEndingWith](https://tinkerpop.apache.org/docs/current/reference/#a-note-on-predicates) 
+  [P: dan, atau, antara, di luar, di dalam](https://tinkerpop.apache.org/docs/current/reference/#a-note-on-predicates) 

## Batasan
<a name="gremlin-with-dfe-limitations"></a>

 Ulangi dengan Batas, Label di dalam traversal berulang dan dedup belum didukung di DFE. 

```
// With Limit inside the repeat traversal
  g.V().has('code','AGR').repeat(out().limit(5)).until(has('code','FRA'))
  
  // With Labels inside the repeat traversal
  g.V().has('code','AGR').repeat(out().as('a')).until(has('code','FRA'))
  
  // With Dedup inside the repeat traversal
  g.V().has('code','AGR').repeat(out().dedup()).until(has('code','FRA'))
```

 Jalur dengan pengulangan bersarang, atau langkah percabangan belum didukung. 

```
// Path with branching steps
  g.V().has('code','AGR').union(identity, outE().inV()).path().by('code')
  
  
  // With nested repeat
  g.V().has('code','AGR').repeat(out().union(identity(), out())).path().by('code')
```

## Perencanaan kueri interleaving
<a name="gremlin-with-dfe-interleaving"></a>

Ketika proses penerjemahan menemukan langkah Gremlin yang tidak memiliki operator DFE asli yang sesuai, sebelum kembali menggunakan Tinkerpop, ia mencoba menemukan bagian kueri perantara lainnya yang dapat dijalankan secara asli di mesin DFE. Ini dilakukan dengan menerapkan logika interleaving ke traversal tingkat atas. Hasilnya adalah langkah-langkah yang didukung digunakan sedapat mungkin.

Terjemahan kueri non-awalan menengah seperti itu direpresentasikan menggunakan `NeptuneInterleavingStep` dalam `explain` dan `profile` output.

Untuk perbandingan kinerja, Anda mungkin ingin mematikan interleaving dalam kueri, sambil tetap menggunakan mesin DFE untuk menjalankan bagian awalan. Atau, Anda mungkin hanya ingin menggunakan TinkerPop mesin untuk eksekusi kueri non-awalan. Anda dapat melakukan ini dengan menggunakan petunjuk `disableInterleaving` kueri.

Sama seperti petunjuk [useDFE](gremlin-query-hints-useDFE.md) kueri dengan nilai `false` mencegah kueri dijalankan di DFE sama sekali, petunjuk `disableInterleaving` kueri dengan nilai `true` mematikan interleaving DFE untuk terjemahan kueri. Contoh:

```
g.with('Neptune#disableInterleaving', true)
 .V().has('genre','drama').in('likes')
```

## Diperbarui Gremlin `explain` dan output `profile`
<a name="gremlin-with-dfe-explain-update"></a>

Gremlin [menjelaskan](gremlin-explain.md) memberikan rincian tentang traversal yang dioptimalkan yang digunakan Neptunus untuk menjalankan kueri. Lihat [contoh `explain` keluaran DFE](gremlin-explain-api.md#gremlin-explain-dfe) untuk contoh seperti apa `explain` output saat mesin DFE diaktifkan.

[API `profile` Gremlin](gremlin-profile-api.md)Menjalankan traversal Gremlin tertentu, mengumpulkan berbagai metrik tentang proses, dan menghasilkan laporan profil yang berisi detail tentang rencana kueri yang dioptimalkan dan statistik runtime dari berbagai operator. Lihat [contoh `profile` keluaran DFE](gremlin-profile-api.md#gremlin-profile-sample-dfe-output) untuk contoh seperti apa `profile` output saat mesin DFE diaktifkan.

**catatan**  
Karena mesin DFE adalah fitur eksperimental yang dirilis dalam mode lab, format `explain` dan `profile` output yang tepat dapat berubah.