

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

# Verwenden der Gremlin-`explain`API in Neptune
<a name="gremlin-explain-api"></a>

Die Amazon-Neptune-Gremlin-`explain`-API gibt den Abfrageplan zurück, der ausgeführt würde, wenn eine bestimmte Abfrage ausgeführt würde. Da die API die Abfrage nicht tatsächlich ausführt, wird der Plan fast sofort zurückgegeben.

Er unterscheidet sich vom Schritt TinkerPop .explain (), um spezifische Informationen für die Neptune-Engine melden zu können.

## In einem Gremlin-`explain`-Bericht enthaltene Informationen
<a name="gremlin-explain-api-results"></a>

Der `explain`-Bericht enthält die folgenden Informationen:
+ Die Abfragezeichenfolge, wie gewünscht.
+ **Die ursprüngliche Traversierung.** Dies ist das TinkerPop Traversal-Objekt, das durch das Parsen der Abfragezeichenfolge in Schritten erzeugt wird. TinkerPop Es entspricht der ursprünglichen Abfrage, die erstellt wurde, indem die Abfrage gegen die `.explain()` ausgeführt wurde. TinkerPop TinkerGraph
+ **Die konvertierte Traversierung.** Dies ist der Neptun-Traversal, der durch die Konvertierung der TinkerPop Traversal in die logische Neptun-Abfrageplandarstellung erzeugt wird. In vielen Fällen wird die gesamte TinkerPop Durchquerung in zwei Neptun-Schritte umgewandelt: einen, der die gesamte Abfrage ausführt (`NeptuneGraphQueryStep`) und einen, der die Ausgabe der Neptune-Abfrage-Engine wieder in Traversers () umwandelt. TinkerPop `NeptuneTraverserConverterStep`
+ **Die optimierte Traversierung.** Dies ist die optimierte Version des Neptune-Abfrageplans, nachdem dieser von mehreren statischen, den Aufwand reduzierenden Optimierern verarbeitet wurde, die die Abfrage basierend auf statischen Analysen und geschätzten Kardinalitäten neu schreiben. Diese Optimierer erledigen Aufgaben wie die Neuanordnung von Operatoren basierend auf der Bereichsanzahl, das Reduzieren unnötiger oder redundanter Operatoren, das Neuanordnen von Filtern, das Verschieben von Operatoren in verschiedene Gruppen und so weiter.
+ **Die Anzahl der Prädikate.** Aufgrund der zuvor beschriebenen Neptune-Indizierungsstrategie können zahlreiche unterschiedliche Prädikate zu Leistungsproblemen führen. Dies gilt insbesondere für Abfragen, die Reverse-Transversal-Operatoren ohne Grenzbezeichnung (`.in` oder `.both`) verwenden. Wenn solche Operatoren verwendet werden und die Anzahl der Prädikate hoch genug ist, zeigt der `explain`-Bericht eine Warnmeldung an.
+ **DFE-Informationen.** Wenn die alternative DFE-Engine aktiviert ist, können die folgenden Traversierungskomponenten in der optimierten Traversierung erscheinen:
  + **`DFEStep`**   –   Ein Neptune-optimierter DFE-Schritt in der Traversierung mit einem untergeordneten `DFENode`. `DFEStep` stellt den Teil des Abfrageplans dar, der in der DFE-Engine ausgeführt wird.
  + **`DFENode`**   –   Enthält die Zwischendarstellung als einen oder mehrere untergeordnete `DFEJoinGroupNodes`.
  + **`DFEJoinGroupNode`**   –   Stellt eine Verbindung von einem oder mehreren `DFENode`- oder `DFEJoinGroupNode`-Elementen dar.
  + **`NeptuneInterleavingStep`**   –   Ein Neptune-optimierter DFE-Schritt in der Traversierung mit einem untergeordneten `DFEStep`.

    Enthält außerdem ein `stepInfo`-Element mit Informationen zur Traversierung, z. B. das Grenzelement, die verwendeten Pfadelemente usw. Diese Informationen werden zur Verarbeitung des untergeordneten `DFEStep` verwendet.

  Eine einfache Art, festzustellen, ob Ihre Abfrage von DFE ausgewertet wird, besteht in der Überprüfung, ob die `explain`-Ausgabe einen `DFEStep` enthält. Jeder Teil der Durchquerung, der nicht Teil von ist, wird nicht von DFE ausgeführt, sondern von der `DFEStep` Engine ausgeführt. TinkerPop 

  Einen Beispielbericht finden Sie unter [Beispiel mit DFE-Aktivierung](#gremlin-explain-dfe).

## Gremlin-Syntax für `explain`
<a name="gremlin-explain-api-syntax"></a>

Die Syntax der `explain`-API ist mit der für die HTTP-API für Abfragen identisch, mit der Ausnahme, dass sie `/gremlin/explain` als Endpunkt anstelle von `/gremlin` verwendet, wie im folgenden Beispiel gezeigt.

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

Die vorherige Abfrage würde die folgende Ausgabe erzeugen.

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

## Nicht umgerechnete Schritte TinkerPop
<a name="gremlin-explain-unconverted-steps"></a>

Im Idealfall werden alle TinkerPop Schritte einer Traversierung von einem eigenen Neptun-Operator abgedeckt. Wenn dies nicht der Fall ist, greift Neptune aufgrund von Lücken in der TinkerPop Bedienerabdeckung auf die Step-Ausführung zurück. Wenn eine Traversierung einen Schritt verwendet, für den Neptune noch keine native Abdeckung besitzt, zeigt der `explain`-Bericht eine Warnung an, die angibt, wo die Lücke aufgetreten ist.

Wenn ein Schritt ohne einen entsprechenden nativen Neptun-Operator angetroffen wird, wird die gesamte Traversierung von diesem Punkt an mithilfe von Schritten ausgeführt, auch wenn nachfolgende TinkerPop Schritte native Neptun-Operatoren haben.

Eine Ausnahme bilden Aufrufe von Neptune-Volltextsuchen. Der NeptuneSearchStep implementiert Schritte ohne systemeigene Entsprechungen als Volltextsuchschritte.

## Beispiel einer `explain`-Ausgabe, wenn es für alle Abfrageschritte native Entsprechungen gibt
<a name="gremlin-explain-all-steps-converted"></a>

Dies ist ein Beispielbericht für `explain` für eine Abfrage, in der es für alle Schritte native Entsprechungen gibt.

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

## Beispiel, in dem es für einige Abfrageschritte keine nativen Entsprechungen gibt
<a name="gremlin-explain-not-all-steps-converted"></a>

Neptune verarbeitet `GraphStep` und `VertexStep` nativ. Wenn Sie jedoch `FoldStep` und `UnfoldStep` einführen, unterscheidet sich die `explain`-Ausgabe:

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

In diesem Fall hebt `FoldStep` die native Ausführung auf. Aber auch die nachfolgende `VertexStep` wird nicht mehr nativ behandelt, da sie den `Fold/Unfold`-Schritten nachgelagert erscheint.

Um Leistung und Kosteneinsparungen zu erzielen, ist es wichtig, dass Sie versuchen, Traversals so zu formulieren, dass der größtmögliche Arbeitsaufwand nativ in der Neptune-Abfrage-Engine erledigt wird, anstatt schrittweise Implementierungen vorzunehmen. TinkerPop 

## Beispiel für eine Abfrage, die Neptune verwendet full-text-search
<a name="gremlin-explain-full-text-search-steps"></a>

Die folgende Abfrage verwendet die Neptune-Volltextsuche:

```
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*")
```

Der Teil `.has("name", "Neptune#fts mark*")` beschränkt die Suche auf Eckpunkte mit `name`, während `.has("Person", "name", "Neptune#fts mark*")` die Suche auf Eckpunkte mit `name` und der Beschriftung `Person` beschränkt. Dies führt zur folgenden Traversierung im `explain`-Bericht:

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

## Beispiel für die Verwendung von `explain` bei DFE-Aktivierung
<a name="gremlin-explain-dfe"></a>

Dies ist ein Beispiel für einen `explain`-Bericht bei Aktivierung der alternativen DFE-Abfrage-Engine:

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

Eine Beschreibung der DFE-spezifischen Abschnitte im Bericht finden Sie unter [Informationen in `explain`](#gremlin-explain-api-results).