

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

# Utilizzo dell'API Gremlin `explain` in Neptune
<a name="gremlin-explain-api"></a>

L'API `explain` di Gremlin in Amazon Neptune restituisce il piano di query che verrebbe eseguito se fosse stata eseguita una determinata query. Poiché l'API non esegue effettivamente la query, il piano viene restituito quasi istantaneamente.

Si differenzia dal passaggio TinkerPop .explain () per poter riportare informazioni specifiche per il motore Neptune.

## Informazioni contenute in un report Gremlin `explain`
<a name="gremlin-explain-api-results"></a>

Il report `explain` contiene le seguenti informazioni:
+ La stringa di query che è stata richiesta.
+ **L'attraversamento originale.** Questo è l'oggetto TinkerPop Traversal prodotto analizzando la stringa di query in passaggi. TinkerPop È equivalente alla query originale prodotta eseguendo la query `.explain()` su. TinkerPop TinkerGraph
+ **L'attraversamento convertito.** Questo è il Neptune Traversal prodotto convertendo il Traversal nella rappresentazione del piano di interrogazione TinkerPop logica di Neptune. In molti casi l'intero TinkerPop attraversamento viene convertito in due passaggi di Neptune: uno che esegue l'intera query () `NeptuneGraphQueryStep` e uno che converte l'output del motore di query Neptune in Traversers (). TinkerPop `NeptuneTraverserConverterStep`
+ **L'attraversamento ottimizzato.** Questa è la versione ottimizzata del piano di query Neptune dopo che è stato eseguito tramite una serie di ottimizzatori di riduzione del lavoro statici che riscrivono la query in base all'analisi statica e alle cardinalità stimate. Questi ottimizzatori eseguono operazioni come riordinare operatori in base a conteggi di intervalli, eliminare operatori superflui o ridondanti, riordinare i filtri, eseguire il push di operatori in gruppi diversi e così via.
+ **Il conteggio di predicati.** A causa della strategia di indicizzazione Neptune descritta in precedenza, avere un numero elevato di predicati diversi può causare problemi di prestazioni. Ciò vale soprattutto per query che utilizzano operatori di attraversamento inverso senza etichetta edge (`.in` o `.both`). Se vengono utilizzati tali operatori e il conteggio di predicati è sufficientemente elevato, il report `explain` visualizza un messaggio di avviso.
+ **Informazioni su DFE.** Quando il motore alternativo DFE è abilitato, nell'attraversamento ottimizzato possono apparire i seguenti componenti di attraversamento:
  + **`DFEStep`**: passaggio DFE ottimizzato per Neptune nell'attraversamento che contiene un oggetto `DFENode` figlio. `DFEStep` rappresenta la parte del piano di query che viene eseguita nel motore DFE.
  + **`DFENode`**: contiene la rappresentazione intermedia come uno o più oggetti `DFEJoinGroupNodes` figlio.
  + **`DFEJoinGroupNode`**: rappresenta l'unione di uno o più elementi `DFENode` o `DFEJoinGroupNode`.
  + **`NeptuneInterleavingStep`**: passaggio DFE ottimizzato per Neptune nell'attraversamento che contiene un oggetto `DFEStep` figlio.

    Contiene anche un elemento `stepInfo` che contiene informazioni sull'attraversamento, come l'elemento di frontiera, gli elementi di percorso utilizzati e così via. Queste informazioni vengono utilizzate per elaborare l'oggetto `DFEStep` figlio.

  Un modo semplice per scoprire se la query viene valutata dal motore DFE consiste nel verificare se l'output `explain` contiene un oggetto `DFEStep`. Qualsiasi parte dell'attraversamento che non fa parte di non verrà eseguita da DFE e `DFEStep` verrà eseguita dal motore. TinkerPop 

  Vedi [Esempio con DFE abilitato](#gremlin-explain-dfe) per un report di esempio.

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

La sintassi dell'API `explain` è identica a quella dell'API HTTP per la query, tranne per il fatto che utilizza `/gremlin/explain` come endpoint anziché `/gremlin`, come nell'esempio seguente.

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

La query precedente produrrebbe il seguente output.

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

## TinkerPop Passi non convertiti
<a name="gremlin-explain-unconverted-steps"></a>

Idealmente, tutte le TinkerPop fasi di un attraversamento hanno una copertura dell'operatore Neptune nativa. In caso contrario, Neptune ricorre all'esecuzione a fasi per eventuali lacune TinkerPop nella copertura degli operatori. Se un attraversamento utilizza un passaggio per il quale Neptune non dispone ancora di copertura nativa, il report `explain` visualizza un avviso che mostra dove si è verificata la lacuna.

Quando viene rilevato un passaggio senza un corrispondente operatore Neptune nativo, l'intero attraversamento da quel punto in poi viene eseguito TinkerPop utilizzando i passaggi, anche se i passaggi successivi hanno operatori Neptune nativi.

L'eccezione a questo è quando viene richiamata la ricerca full-text Neptune. NeptuneSearchStep Implementa passaggi senza equivalenti nativi come passaggi di ricerca a testo completo.

## Esempio di output di `explain` in cui tutti i passaggi di una query dispongono di equivalenti nativi
<a name="gremlin-explain-all-steps-converted"></a>

Di seguito è riportato un esempio di report di `explain` per una query in cui tutti i passaggi dispongono di equivalenti nativi:

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

## Esempio in cui alcune fasi in una query non dispongono di equivalenti nativi
<a name="gremlin-explain-not-all-steps-converted"></a>

Neptune gestisce `GraphStep` e `VertexStep` in modo nativo, ma se si introduce `FoldStep` e `UnfoldStep`, l'output risultante di `explain` è diverso:

```
*******************************************************
                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 questo caso, `FoldStep` interrompe l'esecuzione nativa. Tuttavia, anche la `VertexStep` successiva non viene più gestita in modo nativo perché viene visualizzato a valle delle fasi `Fold/Unfold`.

Per migliorare le prestazioni e ridurre i costi, è importante provare a formulare trasversali in modo che la massima quantità di lavoro possibile venga eseguita nativamente all'interno del motore di query Neptune, anziché implementazioni graduali. TinkerPop 

## Esempio di una query che utilizza Neptune full-text-search
<a name="gremlin-explain-full-text-search-steps"></a>

La query seguente utilizza la ricerca full-text 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*")
```

La parte `.has("name", "Neptune#fts mark*")` limita la ricerca ai vertici con `name`, mentre `.has("Person", "name", "Neptune#fts mark*")` limita la ricerca ai vertici con `name` e all'etichetta `Person`. Ciò ha come risultato il seguente attraversamento nel report di `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}
    }
}]
```

## Esempio di utilizzo di `explain` quando il motore DFE è abilitato
<a name="gremlin-explain-dfe"></a>

Di seguito è riportato un esempio di un report di `explain` quando il motore di query alternativo DFE è abilitato:

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

Per una descrizione delle sezioni specifiche del motore DFE nel report, vedi [Informazioni in `explain`](#gremlin-explain-api-results).