

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Usar a API `explain` do Gremlin no Neptune
<a name="gremlin-explain-api"></a>

A API `explain` do Gremlin no Amazon Neptune exibe o plano de consulta que seria executado se uma consulta especificada fosse executada. Como a API não executa realmente a consulta, o plano é retornado quase instantaneamente.

Ela difere da etapa TinkerPop .explain () para poder relatar informações específicas do mecanismo Neptune.

## Informações contidas em um relatório `explain` do Gremlin
<a name="gremlin-explain-api-results"></a>

Um relatório de `explain` contém as seguintes informações:
+ A string de consulta conforme solicitado.
+ **O percurso original.** Esse é o objeto TinkerPop Traversal produzido pela análise da string de consulta em etapas. TinkerPop É equivalente à consulta original produzida pela execução da consulta `.explain()` em relação ao TinkerPop TinkerGraph.
+ **O percurso convertido.** Essa é a Travessia de Netuno produzida pela conversão da Traversal na representação do plano de consulta lógica de TinkerPop Netuno. Em muitos casos, a TinkerPop travessia inteira é convertida em duas etapas do Neptune: uma que executa a consulta inteira () `NeptuneGraphQueryStep` e outra que converte a saída do mecanismo de consulta Neptune novamente em Traversers (). TinkerPop `NeptuneTraverserConverterStep`
+ **O percurso otimizado.** Essa é a versão otimizada do plano de consulta do Neptune depois que ele é executado por meio de uma série de otimizadores de redução de trabalho estático que reescrevem a consulta com base na análise estática e nas cardinalidades estimadas. Esses otimizadores executam coisas como reordenar operadores com base em contagens de intervalo, remover operadores desnecessários ou redundantes, reorganizar filtros, enviar operadores para grupos diferentes e assim por diante.
+ **A contagem de predicados.** Devido à estratégia de indexação do Neptune descrita anteriormente, ter um grande número de predicados diferentes pode ocasionar problemas de desempenho. Isso é especialmente verdadeiro para consultas que usam operadores de travessia reversa sem rótulo de borda (`.in` ou `.both`). Se esses operadores forem usados e a contagem de predicados for alta o suficiente, o relatório de `explain` exibirá uma mensagem de aviso.
+ **Informações do DFE.** Quando o mecanismo alternativo do DFE está habilitado, os seguintes componentes de percurso podem aparecer no percurso otimizado:
  + **`DFEStep`**: uma etapa otimizada do DFE para Neptune no percurso que contém um `DFENode` secundário. `DFEStep` representa a parte do plano de consulta que é executada no mecanismo do DFE.
  + **`DFENode`**: contém a representação intermediária como um ou mais `DFEJoinGroupNodes` secundários.
  + **`DFEJoinGroupNode`**: representa uma junção de um ou mais elementos `DFENode` ou `DFEJoinGroupNode`.
  + **`NeptuneInterleavingStep`**: uma etapa otimizada do DFE para Netuno no percurso que contém uma `DFEStep` secundária.

    Também apresenta um elemento `stepInfo` que contém informações sobre o percurso, como o elemento de fronteira, os elementos do caminho usados, etc. Essas informações são usadas para processar a `DFEStep` secundária.

  Uma maneira fácil de descobrir se sua consulta está sendo avaliada pelo DFE é conferir se a saída `explain` contém uma `DFEStep`. Qualquer parte da travessia que não faça parte da não `DFEStep` será executada pelo DFE e será executada pelo motor. TinkerPop 

  Consulte [Exemplo com o DFE habilitado](#gremlin-explain-dfe) para obter um exemplo de relatório.

## Sintaxe de `explain` do Gremlin
<a name="gremlin-explain-api-syntax"></a>

A sintaxe da `explain` API é a mesma da API HTTP para consulta, exceto pelo fato de ser usada `/gremlin/explain` como endpoint em vez de`/gremlin`, como nos exemplos a seguir.

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

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

Para obter mais informações, consulte [execute-gremlin-explain-query](https://docs.aws.amazon.com/cli/latest/reference/neptunedata/execute-gremlin-explain-query.html)na Referência de AWS CLI Comandos.

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

Para exemplos de AWS SDK em outras linguagens, como Java, .NET e muito mais, consulte[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)"}'
```

**nota**  
Este exemplo pressupõe que suas AWS credenciais estejam configuradas em seu ambiente. {{us-east-1}}Substitua pela região do seu cluster Neptune.

Para obter mais informações sobre como usar **awscurl** com a autenticação do IAM, consulte[Usar `awscurl` com credenciais temporárias para se conectar com segurança a um cluster de banco de dados com a autenticação do IAM habilitada](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)"}'
```

------

A consulta anterior produziria a saída a seguir.

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

## Etapas não convertidas TinkerPop
<a name="gremlin-explain-unconverted-steps"></a>

Idealmente, todas as TinkerPop etapas de uma travessia têm cobertura nativa do operador Neptune. Quando esse não é o caso, o Neptune recorre à execução de etapas devido a lacunas TinkerPop na cobertura do operador. Se um percurso usar uma etapa para a qual o Neptune ainda não tem cobertura nativa, o relatório do `explain` exibirá um aviso mostrando onde ocorreu o déficit.

Quando uma etapa sem um operador de Netuno nativo correspondente é encontrada, toda a travessia desse ponto em diante é executada TinkerPop usando etapas, mesmo que as etapas subsequentes tenham operadores nativos de Netuno.

A exceção ocorre ao invocar a pesquisa de texto completo do Neptune. O NeptuneSearchStep implementa etapas sem equivalentes nativos como etapas de pesquisa de texto completo.

## Exemplo de saída de `explain` em que todas as etapas de uma consulta têm equivalentes nativos
<a name="gremlin-explain-all-steps-converted"></a>

Veja a seguir um exemplo de relatório `explain` de uma consulta em que todas as etapas têm equivalentes nativos:

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

## Exemplo em que algumas etapas de uma consulta não têm equivalentes nativos
<a name="gremlin-explain-not-all-steps-converted"></a>

O Neptune lida com `GraphStep` e `VertexStep` de forma nativa, mas se você inserir uma `FoldStep` e uma `UnfoldStep`, a saída de `explain` resultante será diferente:

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

Nesse caso, a `FoldStep` interrompe a execução nativa. Mas até mesmo a `VertexStep` subsequente não é mais tratada nativamente porque ela aparece downstream das etapas de `Fold/Unfold`.

Para obter desempenho e economia de custos, é importante que você tente formular percursos para que a quantidade máxima de trabalho possível seja feita de forma nativa dentro do mecanismo de consulta Neptune, em vez de nas implementações por etapas. TinkerPop 

## Exemplo de uma consulta que usa Neptune full-text-search
<a name="gremlin-explain-full-text-search-steps"></a>

A seguinte consulta usa a pesquisa de texto completo do 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*")
```

A parte `.has("name", "Neptune#fts mark*")` limita a pesquisa a vértices com `name`, enquanto `.has("Person", "name", "Neptune#fts mark*")` limita a pesquisa a vértices com `name` e o rótulo `Person`. Isso resulta no seguinte percurso no relatório `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}
    }
}]
```

## Exemplo de uso de `explain` quando o DFE está habilitado
<a name="gremlin-explain-dfe"></a>

Veja um exemplo de relatório `explain` quando o mecanismo de consulta alternativo do DFE está habilitado:

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

Consulte [Informações no `explain`](#gremlin-explain-api-results) para obter uma descrição das seções específicas do DFE no relatório.