

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

# 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 `explain` API sama dengan API HTTP untuk kueri, kecuali yang digunakan `/gremlin/explain` sebagai titik akhir, bukan`/gremlin`, seperti pada contoh berikut.

------
#### [ AWS CLI ]

```
aws neptunedata execute-gremlin-explain-query \
  --endpoint-url https://{{your-neptune-endpoint}}:{{port}} \
  --gremlin-query "g.V().limit(1)"
```

Untuk informasi selengkapnya, lihat [execute-gremlin-explain-query](https://docs.aws.amazon.com/cli/latest/reference/neptunedata/execute-gremlin-explain-query.html)di Referensi AWS CLI Perintah.

------
#### [ SDK ]

```
import boto3
from botocore.config import Config

client = boto3.client(
    'neptunedata',
    endpoint_url='https://{{your-neptune-endpoint}}:{{port}}',
    config=Config(read_timeout=None, retries={'total_max_attempts': 1})
)

response = client.execute_gremlin_explain_query(
    gremlinQuery='g.V().limit(1)'
)

print(response['output'])
```

Untuk contoh AWS SDK dalam bahasa lain seperti Java, .NET, dan lainnya, lihat[AWS SDK](access-graph-gremlin-sdk.md).

------
#### [ awscurl ]

```
awscurl https://{{your-neptune-endpoint}}:{{port}}/gremlin/explain \
  --region {{us-east-1}} \
  --service neptune-db \
  -X POST \
  -d '{"gremlin":"g.V().limit(1)"}'
```

**catatan**  
Contoh ini mengasumsikan bahwa AWS kredensil Anda dikonfigurasi di lingkungan Anda. Ganti {{us-east-1}} dengan Wilayah cluster Neptunus Anda.

Untuk informasi selengkapnya tentang menggunakan **awscurl** autentikasi IAM, lihat. [Menggunakan `awscurl` dengan kredensyal sementara untuk terhubung dengan aman ke cluster DB dengan otentikasi IAM diaktifkan](iam-auth-connect-command-line.md#iam-auth-connect-awscurl)

------
#### [ curl ]

```
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.