Utilisation de l'API Gremlin explain dans Neptune - Amazon Neptune

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Utilisation de l'API Gremlin explain dans Neptune

L'API Amazon Neptune Gremlin explain renvoie le plan de requête qui serait exécuté si une requête spécifique était exécutée. Comme l'API n'exécute pas réellement la requête, le plan est renvoyé presque instantanément.

Elle diffère de l'étape TinkerPop .explain () afin de pouvoir rapporter des informations spécifiques au moteur Neptune.

Informations qui se trouvent dans un rapport Gremlin explain

Un rapport explain contient les informations suivantes :

  • Chaîne de requête demandée.

  • Traversée d'origine. Il s'agit de l'objet TinkerPop Traversal produit en analysant la chaîne de requête en TinkerPop étapes. Elle est équivalente à la requête d'origine produite en exécutant la requête .explain() sur le TinkerPop TinkerGraph.

  • Traversée convertie. Il s'agit du Neptune Traversal produit en convertissant le TinkerPop Traversal en représentation logique du plan de requêtes Neptune. Dans de nombreux cas, l'intégralité de la TinkerPop traversée est convertie en deux étapes Neptune : l'une qui exécute la requête complète NeptuneGraphQueryStep () et l'autre qui reconvertit la sortie du moteur de requêtes Neptune en Traversers (). TinkerPop NeptuneTraverserConverterStep

  • Traversée optimisée. Il s'agit de la version optimisée du plan de requête Neptune une fois qu'il a été exécuté via une série d'optimiseurs statiques de réduction du travail qui réécrivent la requête en fonction de l'analyse statique et des cardinalités estimées. Ces optimiseurs effectuent des opérations telles que la réorganisation des opérateurs en fonction du nombre de plages, la suppression des opérateurs superflus ou redondants, la réorganisation des filtres, le transfert des opérateurs dans différents groupes, etc.

  • Nombre de prédicats. En raison de la stratégie d'indexation Neptune décrite précédemment, le fait d'avoir un grand nombre de prédicats différents peut entraîner des problèmes de performances. Cela est particulièrement vrai pour les requêtes qui utilisent des opérateurs de traversée inverse sans étiquette d'arc (.in ou .both). Si ces opérateurs sont utilisés et que le nombre de prédicats est suffisamment élevé, le rapport explain affiche un message d'avertissement.

  • Informations DFE. Lorsque le moteur alternatif DFE est activé, les composants de traversée suivants peuvent apparaître dans la traversée optimisée :

    • DFEStep : étape DFE optimisée pour Neptune dans la traversée qui contient un objet DFENode enfant. DFEStep représente la partie du plan de requête exécutée dans le moteur DFE.

    • DFENode : contient la représentation intermédiaire sous la forme d'un ou de plusieurs objets DFEJoinGroupNodes enfants.

    • DFEJoinGroupNode : représente une jointure d'un ou de plusieurs éléments DFENode ou DFEJoinGroupNode.

    • NeptuneInterleavingStep : étape DFE optimisée pour Neptune dans la traversée qui contient un objet DFEStep enfant.

      Contient également un élément stepInfo comportant des informations sur la traversée, telles que l'élément frontière, les éléments de chemin utilisés, etc. Ces informations sont utilisées pour traiter l'objet DFEStep enfant.

    Un moyen simple de savoir si votre requête est évaluée par le DFE est de vérifier si la sortie explain contient un objet DFEStep. Toute partie de la traversée qui n'en fait pas partie ne DFEStep sera pas exécutée par DFE et sera exécutée par le TinkerPop moteur.

    Consultez Exemple avec le DFE activé pour voir un exemple de rapport.

Syntaxe Gremlin explain

La syntaxe de l'API explain est identique à celle de l'API HTTP de la requête, sauf qu'elle utilise /gremlin/explain comme point de terminaison au lieu de /gremlin, comme dans l'exemple suivant.

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

La requête précédente génèrerait la sortie suivante.

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

Étapes non converties TinkerPop

Idéalement, toutes les TinkerPop étapes d'une traversée bénéficient d'une couverture native de l'opérateur Neptune. Lorsque ce n'est pas le cas, Neptune recourt à l'exécution par TinkerPop étapes pour combler les lacunes dans la couverture de ses opérateurs. Si une traversée utilise une étape pour laquelle Neptune n'a pas encore de couverture native, le rapport explain affiche un avertissement indiquant où l'écart s'est produit.

Lorsqu'une étape sans opérateur Neptune natif correspondant est rencontrée, la totalité de la traversée à partir de ce point est exécutée par TinkerPop étapes, même si les étapes suivantes comportent des opérateurs Neptune natifs.

L'exception est lorsque la recherche en texte intégral Neptune est appelée. Il NeptuneSearchStep implémente des étapes sans équivalents natifs sous forme d'étapes de recherche en texte intégral.

Exemple de sortie explain où toutes les étapes d'une requête ont des équivalents natifs

Voici un exemple de rapport explain concernant une requête pour laquelle toutes les étapes ont des équivalents natifs :

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

Exemple où certaines étapes d'une requête n'ont pas d'équivalents natifs

Neptune gère GraphStep et VertexStep en mode natif, mais si vous introduisez un élément FoldStep et un élément UnfoldStep , la sortie explain générée est différente :

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

Dans ce cas, l'élément FoldStep vous fait quitter l'exécution native. Même l'étape VertexStep suivante n'est plus gérée en mode natif, car elle apparaît en aval des étapes Fold/Unfold.

Pour des raisons de performances et de réduction des coûts, il est important que vous essayiez de formuler des traversées de manière à ce que le maximum de travail possible soit effectué de manière native dans le moteur de requêtes Neptune, plutôt que de procéder à des implémentations étape par étape. TinkerPop

Exemple de requête utilisant Neptune full-text-search

La requête suivante utilise la recherche en texte intégral 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 partie .has("name", "Neptune#fts mark*") limite la recherche aux sommets avec name, alors que .has("Person", "name", "Neptune#fts mark*") limite la recherche aux sommets avec name et l'étiquette Person. Le résultat est la traversée suivante dans le rapport 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} } }]

Exemple d'utilisation d'explain lorsque le DFE est activé

Voici un exemple de rapport explain lorsque le moteur de requête alternatif DFE est activé :

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

Consultez Informations dans explain pour voir une description des sections spécifiques au DFE dans le rapport.