

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.

# Migration de Neo4j vers Amazon Neptune
<a name="migrating-from-neo4j"></a>

Neo4j et Amazon Neptune sont des bases de données orientées graphe conçues pour les charges de travail de graphe transactionnelles en ligne qui prennent en charge le modèle de données de graphes à propriétés étiquetées. Ces similitudes font de Neptune un choix courant pour les clients qui cherchent à migrer leurs applications Neo4j actuelles. Toutefois, ces migrations ne se résument pas à un simple « lift and shift », car il existe des différences de langage, de prise en charge des fonctionnalités, de caractéristiques opérationnelles, d'architecture de serveur et de fonctionnalités de stockage entre les deux bases de données.

Cette page décrit le processus de migration et présente les éléments à prendre en compte avant de migrer une application orientée graphe Neo4j vers Neptune. Ces considérations s'appliquent généralement à toute application orientée graphe Neo4j, qu'elle soit alimentée par une base de données Community, Enterprise ou Aura. Bien que chaque solution soit unique et puisse nécessiter des procédures supplémentaires, toutes les migrations suivent le même schéma général.

Chacune des étapes décrites dans les sections suivantes inclut des considérations et des recommandations visant à simplifier le processus de migration. En outre, il existe [des outils open source et des billets de blog](migration-resources.md) décrivant le processus, ainsi qu'une [section sur la compatibilité des fonctionnalités](migration-compatibility.md) avec les options architecturales recommandées.

**Topics**
+ [Informations générales sur la migration de Neo4j vers Neptune](migrating-from-neo4j-general.md)
+ [Préparation à la migration de Neo4j vers Neptune](preparing-to-migrate-from-neo4j.md)
+ [Provisionnement de l'infrastructure lors de la migration de Neo4j vers Neptune](migration-provisioning-infrastructure.md)
+ [Migration des données de Neo4j vers Neptune](migration-data-migration.md)
+ [Migration d'une application de Neo4j vers Neptune](migration-app-migration.md)
+ [Compatibilité de Neptune avec Neo4j](migration-compatibility.md)
+ [Réécriture des requêtes Cypher pour les exécuter dans openCypher sur Neptune](migration-opencypher-rewrites.md)
+ [Ressources pour la migration de Neo4j vers Neptune](migration-resources.md)

# Informations générales sur la migration de Neo4j vers Neptune
<a name="migrating-from-neo4j-general"></a>

Grâce à la prise en [charge du langage de requête openCypher](feature-opencypher-compliance.md) par Neptune, vous pouvez déplacer la plupart des charges de travail Neo4j qui utilisent le protocole Bolt ou HTTPS vers Neptune. Cependant, openCypher est une spécification open source qui contient la plupart des fonctionnalités prises en charge par d'autres bases de données telles que Neo4j, mais pas toutes.

Bien qu'il soit compatible à bien des égards, Neptune ne remplace pas directement Neo4j. Neptune est un service de base de données orientée graphe entièrement géré et doté de fonctionnalités d'entreprise telles que la haute disponibilité et la haute durabilité. Son architecture est différente de celle de Neo4j. Neptune repose sur une instance, avec une seule instance d'enregistreur principale et jusqu'à 15 instances de réplica en lecture qui vous permettent de mettre à l'échelle horizontalement la capacité de lecture. Avec [Neptune sans serveur](neptune-serverless.md), vous pouvez automatiquement augmenter ou diminuer la capacité de calcul en fonction du volume de requêtes. Cela est indépendant du stockage Neptune, qui est mis à l'échelle automatiquement à mesure que vous ajoutez des données.

Neptune prend en charge la [spécification standard open source openCypher, version 9](https://s3.amazonaws.com/artifacts.opencypher.org/openCypher9.pdf). Chez AWS, nous pensons que l'open source est bénéfique pour tout le monde et nous nous engageons à la fois à apporter la valeur de l'open source à nos clients et à apporter l'excellence opérationnelle AWS aux communautés open source.

Cependant, de nombreuses applications exécutées sur Neo4j utilisent également des fonctionnalités propriétaires qui ne sont pas open source et que Neptune ne prend pas en charge. Par exemple, Neptune ne prend pas en charge les procédures APOC, certaines clauses et fonctions spécifiques à Cypher ni les types de données `Char`, `Date` et `Duration`. Neptune convertit automatiquement les types de données manquants en [types de données pris en charge](bulk-load-tutorial-format-opencypher.md#bulk-load-tutorial-format-opencypher-data-types).

Outre OpenCypher, Neptune prend également en charge le langage de requête [Apache TinkerPop Gremlin](https://tinkerpop.apache.org/docs/current/reference/#traversal) pour les graphes de propriétés (ainsi que SPARQL pour les données RDF). Gremlin peut interagir avec openCypher sur le même graphe de propriétés, et dans de nombreux cas, vous pouvez utiliser Gremlin pour fournir des fonctionnalités qu'openCypher ne fournit pas. Vous trouverez ci-dessous une comparaison rapide des deux langages :


|  | openCypher | Gremlin | 
| --- | --- | --- | 
| Style | Déclaratif | Impératif | 
| Syntaxe |  Mise en correspondance des modèles <pre>Match p=(a)-[:route]->(d)<br />WHERE a.code='ANC'<br />RETURN p<br /></pre>  |  Basé sur la traversée <pre>g.V().has('code', 'ANC').<br />out('route').path().<br />by(elementMap())</pre>  | 
| Facilité d'utilisation | Inspiré de SQL, lisible par les non-programmeurs | Courbe d'apprentissage plus abrupte, similaire à celle des langages de programmation tels que Java | 
| Flexibilité | Faible | Élevée | 
| Prise en charge des requêtes | Requêtes basées sur des chaînes | Requêtes basées sur des chaînes ou code intégré pris en charge par les bibliothèques clientes | 
| Clients | HTTPS et Bolt | HTTPS et Websocket | 

En général, il n'est pas nécessaire de modifier votre modèle de données pour migrer de Neo4j vers Neptune, car Neo4j et Neptune prennent en charge les données de graphes de propriétés étiquetées (LPG). Neptune présente toutefois certaines différences d'architecture et de modèle de données dont vous pouvez tirer parti pour optimiser les performances. Par exemple :
+ Neptune est traitée comme un IDs citoyen de premier ordre.
+ Neptune utilise des [politiques Gestion des identités et des accès AWS (IAM)](iam-auth.md) pour sécuriser l'accès aux données de graphe de manière flexible et granulaire.
+ Neptune propose plusieurs manières d'[utiliser les blocs-notes Jupyter](graph-notebooks.md) pour exécuter des requêtes et [visualiser les résultats](notebooks-visualization.md). Neptune fonctionne également avec des [outils de visualisation tiers](visualization-tools.md).
+ Bien que Neptune n'ait aucun substitut à la bibliothèque Graph Data Science (GDS) de Neo4j, Neptune prend actuellement en charge l'analytique de graphe par le biais de diverses solutions. Par exemple, plusieurs [exemples de blocs-notes](https://github.com/aws/graph-notebook/tree/main/src/graph_notebook/notebooks/01-Neptune-Database/03-Sample-Applications/06-Data-Science-Samples) montrent comment tirer parti de l'[intégration de Neptune avec AWS le SDK Pandas dans les](https://github.com/amazon-archives/fully-automated-neo4j-to-neptune) environnements Python pour exécuter des analyses sur des données graphiques.

N'hésitez pas à contacter l'équipe chargée AWS de votre AWS compte ou à contacter l'équipe chargée de votre compte si vous avez des questions. Nous tenons compte de vos commentaires pour traiter en priorité les nouvelles fonctionnalités qui répondront à vos besoins.

# Préparation à la migration de Neo4j vers Neptune
<a name="preparing-to-migrate-from-neo4j"></a>

 La migration de la base de données de graphes Neo4j vers le service de base de données de graphes Neptune peut être abordée de deux manières principales : replateforme ou refactorisation/réarchitecture. L'approche de replateforme implique de modifier le modèle de données et l'architecture d'application existants afin de tirer le meilleur parti des capacités de Neptune, tandis que l'approche de refactorisation vise à trouver des composants équivalents dans Neptune afin de créer une implémentation comparable. Dans la pratique, une combinaison de ces stratégies est souvent utilisée, car le processus de migration consiste à équilibrer l'architecture Neptune cible avec les contraintes et les exigences de l'implémentation existante de Neo4j. Quelle que soit l'approche, l'essentiel est de repartir des cas d'utilisation de l'application pour concevoir le modèle de données, les requêtes et l'architecture globale qui répondent le mieux à vos besoins. 

## Approches en matière de migration
<a name="migration-approaches"></a>

Lors de la migration d'une application Neo4j vers Neptune, nous recommandons l'une des deux stratégies suivantes : le changement de plateforme ou la refactorisation/restructuration de l'architecture. Pour plus d'informations sur les stratégies de migration, consultez le billet de blog [6 Strategies for Migrating Applications to the Cloud](https://aws.amazon.com/blogs/enterprise-strategy/6-strategies-for-migrating-applications-to-the-cloud/) de Stephen Orban.

L'approche de *replateforme, parfois appelée approche *lift-tinker-and-shift**, implique les étapes suivantes :
+ Identifiez les cas d'utilisation auxquels votre application est censée répondre.
+ Modifiez le modèle de données de graphe et l'architecture d'application existants pour répondre au mieux à ces besoins de charge de travail en utilisant les fonctionnalités de Neptune.
+ Déterminez comment migrer les données, les requêtes et les autres parties de l'application source vers le modèle et l'architecture cibles.

Cette approche rétroactive vous permet de migrer votre application vers le type de solution Neptune que vous pourriez concevoir s'il s'agissait d'un tout nouveau projet.

L'*approche de refactorisation*, en revanche, implique les étapes suivantes :
+ Identifiez les composants de la mise en œuvre existante, notamment l'infrastructure, les données, les requêtes et les fonctionnalités de l'application.
+ Trouvez des équivalents dans Neptune qui pourront être utilisés pour créer une implémentation comparable.

Cette approche avant-gardiste vise à remplacer une implémentation par une autre.

Dans la pratique, il est probable que vous adoptiez une combinaison de ces deux approches. Vous pouvez commencer par un cas d'utilisation, concevoir l'architecture Neptune cible, puis vous tourner vers l'implémentation Neo4j existante pour identifier les contraintes et les invariants à respecter. Par exemple, vous devrez peut-être poursuivre l'intégration avec d'autres systèmes externes ou continuer à proposer des offres spécifiques APIs aux utilisateurs de votre application graphique. Grâce à ces informations, vous pourrez déterminer quelles données existantes transférer vers votre modèle cible, et celles qui doivent aller ailleurs.

À d'autres moments, vous commencerez peut-être par analyser un élément spécifique de votre implémentation Neo4j comme étant la meilleure source d'informations sur la tâche que votre application est censée accomplir. Ce type d'archéologie dans l'application existante peut aider à définir un cas d'utilisation que vous pourrez ensuite concevoir en utilisant les fonctionnalités de Neptune.

Que vous développiez une nouvelle application à l'aide de Neptune ou que vous migriez une application existante à partir de Neo4j, nous vous recommandons de travailler de manière rétroactive en partant des cas d'utilisation pour concevoir un modèle de données, un ensemble de requêtes et une architecture d'application répondant aux besoins de votre entreprise.

# Différences architecturales entre Neptune et Neo4j
<a name="migration-architectural-differences"></a>

Lorsque les clients envisagent pour la première fois de migrer une application de Neo4j vers Neptune, il est souvent tentant d'effectuer une like-to-like comparaison basée sur la taille de l'instance. Cependant, les architectures de Neo4j et Neptune présentent des différences fondamentales. Neo4j est basé sur une all-in-one approche dans laquelle le chargement des données, l'ETL des données, les requêtes d'application, le stockage des données et les opérations de gestion se déroulent tous dans le même ensemble de ressources de calcul, telles que les instances EC2.

En revanche, Neptune est une base de données orientée graphe axée sur l'OLTP. Son architecture sépare les responsabilités, et ses ressources sont découplées afin qu'elles puissent se mettre à l'échelle de manière dynamique et indépendante.

Lors de la migration de Neo4j vers Neptune, déterminez les exigences de durabilité, de disponibilité et d'évolutivité des données de votre application. L'architecture de cluster de Neptune simplifie la conception d'applications nécessitant une durabilité, une disponibilité et une capacité de mise à l’échelle élevées. En comprenant l'architecture de cluster de Neptune, vous pourrez concevoir une topologie de cluster Neptune qui répond à ces exigences.

## Architecture de cluster de Neo4j
<a name="migration-neo4j-cluster-architecture"></a>

De nombreuses applications de production utilisent le [clustering causal](https://neo4j.com/docs/operations-manual/current/clustering/introduction/) de Neo4j pour garantir la durabilité, la haute disponibilité et la capacité de mise à l’échelle des données. L'architecture de clustering de Neo4j utilise des instances de serveur principal et de réplica en lecture :
+ Les serveurs principaux assurent la durabilité des données et la tolérance aux pannes en répliquant les données à l'aide du protocole Raft.
+ Les réplicas en lecture utilisent l'expédition des journaux de transactions pour répliquer les données de manière asynchrone pour les charges de travail à haut débit de lecture.

Chaque instance d'un cluster, qu'il s'agisse du serveur principal ou d'un réplica en lecture, contient une copie complète des données du graphe.

## Architecture de cluster de Neptune
<a name="migration-neptune-cluster-architecture"></a>

Un [cluster Neptune](feature-overview-db-clusters.md) est composé d'une instance d'enregistreur principale et d'un maximum de 15 instances de réplica en lecture. Toutes les instances du cluster partagent le même service de stockage distribué sous-jacent, distinct des instances.
+ L'instance d'enregistreur principale coordonne toutes les opérations d'écriture dans la base de données et est évolutive verticalement pour assurer une prise en charge flexible des différentes charges de travail d'écriture. Elle prend également en charge les opérations de lecture.
+ Les instances de réplica en lecture prennent en charge les opérations de lecture à partir du volume de stockage sous-jacent et vous permettent d'effectuer une mise à l'échelle horizontale pour répondre aux besoins des charges de travail à haut débit de lecture. Elles assurent également une haute disponibilité en servant de cibles de basculement pour l'instance principale.
**Note**  
Pour les charges de travail impliquant un grand nombre d'écritures, il est préférable de mettre à l'échelle les instances de réplica en lecture pour qu'elles soient de la même taille que l'instance d'enregistreur, afin de garantir la cohérence des lecteurs face aux modifications des données.
+ Le volume de stockage sous-jacent met automatiquement à l'échelle la capacité de stockage à mesure que les données de votre base de données augmentent, jusqu'à 128 tébioctets (Tio) de stockage.

Les tailles d'instance sont dynamiques et indépendantes. Chaque instance peut être redimensionnée pendant l'exécution du cluster, et des réplicas en lecture peuvent être ajoutés ou supprimés pendant l'exécution du cluster.

La fonctionnalité [Neptune sans serveur](neptune-serverless.md) permet d'augmenter ou de diminuer automatiquement la capacité de calcul en fonction de la hausse ou de la baisse de la demande. Cela permet non seulement de réduire votre charge administrative, mais également de configurer la base de données pour qu'elle puisse gérer les pics de demande importants sans dégrader les performances ni vous obliger à provisionner plus de ressources que nécessaire.

Vous pouvez arrêter un cluster Neptune pendant une durée pouvant atteindre sept jours.

Neptune prend également en charge l'[autoscaling](manage-console-autoscaling.md) afin d'ajuster automatiquement la taille des instances de lecteur en fonction de la charge de travail.

Grâce à la [fonctionnalité de base de données globale](neptune-global-database.md) de Neptune, vous pouvez mettre en miroir un cluster dans jusqu'à cinq autres régions.

Neptune est également [tolérant aux pannes par conception](backup-restore-overview-fault-tolerance.md) :
+ Le volume de cluster qui fournit le stockage de données à toutes les instances du cluster couvre plusieurs zones de disponibilité (AZs) en une seule Région AWS. Chaque zone de disponibilité contient une copie intégrale des données du cluster.
+ Si l'instance principale devient indisponible, Neptune bascule automatiquement vers un réplica en lecture existant sans aucune perte de données, généralement en moins de 30 secondes. S'il n'existe aucune réplica en lecture dans le cluster, Neptune provisionne automatiquement une nouvelle instance principale, là aussi sans aucune perte de données.

Autrement dit, lors de la migration d'un cluster causal Neo4j vers Neptune, vous n'avez pas à concevoir explicitement la topologie du cluster pour une haute durabilité des données et une disponibilité élevée. Cela vous permet de dimensionner votre cluster en fonction des charges de travail de lecture et d'écriture attendues et de toute exigence de disponibilité accrue que vous pourriez avoir, en seulement quelques étapes :
+ Pour mettre à l'échelle les opérations de lecture, [ajoutez des instances de réplica en lecture](feature-overview-db-clusters.md#feature-overview-read-replicas) ou activez la fonctionnalité [Neptune sans serveur](neptune-serverless.md).
+ Pour améliorer la disponibilité, distribuez l'instance principale et lisez les répliques dans votre cluster sur plusieurs zones de disponibilité (AZs).
+ Pour réduire le temps de basculement, provisionnez au moins une instance de réplica en lecture qui servira de cible de basculement pour l'instance principale. Vous pouvez déterminer l'ordre dans lequel les réplicas en lecture sont promus en instance principale après un échec [en affectant à chaque réplica une priorité](manage-console-add-replicas.md). Il est recommandé de s'assurer qu'une cible de basculement possède une classe d'instances capable de gérer la charge de travail d'écriture de votre application si elle est promue en instance principale.

# Différences de stockage des données entre Neptune et Neo4j
<a name="migration-storage-differences"></a>

Neptune utilise un [modèle de données de graphe](feature-overview-data-model.md) basé sur un modèle de quadruplet natif. Lorsque vous migrez vos données vers Neptune, il existe plusieurs différences dont vous devez tenir compte dans l'architecture du modèle de données et de la couche de stockage afin d'utiliser de manière optimale le stockage partagé distribué et évolutif fourni par Neptune :
+ Neptune n'utilise aucun schéma ni aucune contrainte définis de manière explicite. Il vous permet d'ajouter des nœuds, des arêtes et des propriétés de manière dynamique sans avoir à définir le schéma à l'avance. Neptune ne limite pas les valeurs et les types de données stockées, sauf indication contraire spécifiée dans les [limites Neptune](limits.md#limits-properties). Dans le cadre de l'architecture de stockage de Neptune, les données sont également [automatiquement indexées](feature-overview-storage-indexing.md) de manière à gérer la plupart des modèles d'accès les plus courants. Cette architecture de stockage élimine les coûts opérationnels liés à la création et à la gestion du schéma de base de données et à l'optimisation des index.
+ Neptune fournit une architecture de stockage distribuée et partagée unique qui s'adapte automatiquement par tranches de 10 Go à mesure que les besoins de stockage de votre base de données augmentent, jusqu'à 128 tébioctets (Tio). Cette couche de stockage est fiable, durable et tolérante aux pannes. Les données sont copiées six fois : deux fois dans chacune des trois zones de disponibilité. Elle fournit par défaut à tous les clusters Neptune une couche de stockage de données hautement disponible et tolérante aux pannes. L'architecture de stockage de Neptune réduit les coûts et évite d'avoir à provisionner du stockage ou plus de stockage que nécessaire pour faire face à la croissance future des données.

Avant de migrer vos données vers Neptune, il est conseillé de vous familiariser avec le [modèle de données du graphe de propriétés](feature-overview-storage-indexing.md#feature-overview-storage-indexing-gremlin) et la [sémantique des transactions](transactions.md) de Neptune. 

# Différences opérationnelles entre Neptune et Neo4j
<a name="migration-operational-differences"></a>

Neptune est un service entièrement géré qui automatise la plupart des tâches opérationnelles normales que vous devez effectuer lorsque vous utilisez des bases de données sur site ou autogérées telles que Neo4j Enterprise ou Community Edition :
+ **[Sauvegardes automatisées](backup-restore.md#backup-restore-overview-backups)** : Neptune sauvegarde automatiquement le volume de votre cluster et conserve la sauvegarde pendant une période de rétention que vous spécifiez (comprise entre 1 et 35 jours). Ces sauvegardes étant continues et incrémentielles, vous pouvez rapidement opérer une restauration à un point quelconque de la période de rétention. Aucun impact sur les performances ou interruption du service de base de données ne se produit lors de l’écriture des données de sauvegarde.
+ **[Instantanés manuels](backup-restore.md)** : Neptune vous permet de créer un instantané du volume de stockage de votre cluster de bases de données pour sauvegarder l'intégralité du cluster. Ce type d'instantané pourra être utilisé pour restaurer la base de données, en faire une copie et la partager entre les comptes.
+ **[Clonage](manage-console-cloning.md)** : Neptune prend en charge une fonctionnalité de clonage qui vous permet de créer rapidement des clones économiques d'une base de données. Les clones utilisent un copy-on-write protocole qui ne nécessite qu'un minimum d'espace supplémentaire après leur création. Le clonage de base de données est un moyen efficace de tester les nouvelles fonctionnalités ou mises à niveau de Neptune sans affecter le cluster d'origine.
+ **[Surveillance](monitoring.md)** : Neptune propose différentes méthodes pour surveiller les performances et l'utilisation de votre cluster, notamment :
  + Statut de l'instance
  + Intégration avec Amazon CloudWatch et AWS CloudTrail
  + Fonctionnalités du journal d'audit
  + Notifications d’événements
  + Identification
+ **[Sécurité](security.md)** : Neptune fournit un environnement sécurisé par défaut. Un cluster réside dans un VPC privé qui permet d'isoler le réseau des autres ressources. Tout le trafic est crypté via SSL, et toutes les données sont cryptées au repos à l'aide de AWS KMS.

  [En outre, Neptune s'intègre à Gestion des identités et des accès AWS (IAM) pour fournir une authentification.](iam-auth.md) En spécifiant des [clés de condition IAM](iam-condition-keys.md), vous pouvez utiliser des politiques IAM pour fournir un contrôle d'accès précis au niveau des [actions sur les données](iam-data-access-policies.md).

## Différences d'outils et d'intégration entre Neptune et Neo4j
<a name="migration-tooling-differences"></a>

Neptune possède une architecture d'intégrations et d'outils différente de celle de Neo4j, ce qui peut avoir un impact sur l'architecture de votre application. Neptune utilise les ressources de calcul du cluster pour traiter les requêtes, mais utilise d'autres best-in-class AWS services pour des fonctionnalités telles que la recherche en texte intégral (utilisation OpenSearch), ETL (utilisation de Glue), etc. Pour obtenir la liste complète de ces intégrations, consultez [Intégrations Neptune](integrations.md).

# Provisionnement de l'infrastructure lors de la migration de Neo4j vers Neptune
<a name="migration-provisioning-infrastructure"></a>

Les clusters Amazon Neptune sont conçus pour évoluer en trois dimensions : stockage, capacité d'écriture et capacité de lecture. Les sections ci-dessous présentent les options spécifiques à prendre en compte lors de la migration.

## Allocation du stockage
<a name="migration-provisioning-storage"></a>

Le stockage de tout cluster Neptune est automatiquement provisionné, sans aucune charge administrative de votre part. Il est redimensionné dynamiquement par tranches de 10 Go à mesure que les besoins de stockage du cluster augmentent. Par conséquent, vous n'avez pas besoin d'estimer le stockage pour faire face à la croissance future des données ni de le provisionner, voire d'en provisionner plus que nécessaire.

## Provisionnement de la capacité d'écriture
<a name="migration-provisioning-write-capacity"></a>

Neptune fournit une instance d'enregistreur unique qui peut être mise à l'échelle verticalement pour atteindre n'importe quelle taille d'instance disponible sur la [page de tarification de Neptune](https://aws.amazon.com/neptune/pricing/). Lors de la lecture et de l'écriture de données dans une instance d'enregistreur, toutes les transactions sont conformes à l'ACID, avec un isolement des données tel que défini dans [Niveaux d'isolement des transactions dans Neptune](transactions-neptune.md).

Le choix d'une taille optimale pour une instance services d'enregistreur nécessite l'exécution de tests de charge permettant de déterminer la taille d'instance optimale pour votre charge de travail. Toute instance dans Neptune peut être redimensionnée à tout moment en [modifiant la classe d'instances de base de données](manage-console-instances-modify.md). Vous pouvez estimer la taille d'une instance de départ en fonction de la simultanéité et de la latence moyenne des requêtes, comme décrit ci-dessous dans [Estimation de la taille d'instance optimale lors du provisionnement du cluster](#migration-provisioning-instance-sizing).

## Provisionnement de la capacité de lecture
<a name="migration-provisioning-read-capacity"></a>

Neptune est conçu pour mettre à l'échelle les instances de réplica en lecture à la fois horizontalement, en en ajoutant jusqu'à 15 au sein d'un cluster (ou plus dans une [base de données globale Neptune](neptune-global-database.md)), et verticalement selon la taille d'instance disponible sur la [page de tarification de Neptune](https://aws.amazon.com/neptune/pricing/). Toutes les instances de réplica en lecture Neptune utilisent le même volume de stockage sous-jacent, ce qui permet une réplication transparente des données avec un retard minimal.

En plus de permettre la mise à l'échelle horizontale des demandes de lecture au sein d'un cluster Neptune, les réplicas en lecture servent également de cibles de basculement pour l'instance d'enregistreur afin de garantir une haute disponibilité. Consultez [Directives opérationnelles de base Amazon Neptune](best-practices-general-basic.md) pour obtenir des suggestions sur la manière de déterminer le nombre et le placement appropriés des réplicas en lecture dans votre cluster.

Pour les applications où la connectivité et la charge de travail sont imprévisibles, Neptune prend également en charge une [fonctionnalité d'autoscaling](manage-console-autoscaling.md) qui permet d'ajuster automatiquement le nombre de réplicas Neptune en fonction de critères que vous spécifiez.

Pour déterminer une taille et un nombre optimaux d'instances de réplication en lecture, il est nécessaire d'exécuter des tests de charge afin de déterminer les caractéristiques de la charge de travail de lecture qu'elles doivent prendre en charge. Toute instance dans Neptune peut être redimensionnée à tout moment en [modifiant la classe d'instances de base de données](manage-console-instances-modify.md). Vous pouvez estimer la taille d'une instance de départ en fonction de la simultanéité et de la latence moyenne des requêtes, comme décrit dans la [section suivante](#migration-provisioning-instance-sizing).

## Utilisation de Neptune sans serveur pour mettre automatiquement à l'échelle les instances de lecteur et d'enregistreur selon les besoins
<a name="migration-provisioning-serverless"></a>

Bien qu'il soit souvent utile d'estimer la capacité de calcul requise par les charges de travail prévues, vous pouvez configurer la fonctionnalité [Neptune sans serveur](neptune-serverless.md) pour augmenter ou diminuer automatiquement la capacité de lecture et d'écriture. Cela peut vous aider à répondre aux besoins en cas de hausse soudaine tout en réduisant automatiquement la capacité lorsque la demande diminue.

## Estimation de la taille d'instance optimale lors du provisionnement du cluster
<a name="migration-provisioning-instance-sizing"></a>

L'estimation de la taille d'instance optimale nécessite de connaître la latence moyenne des requêtes dans Neptune, lorsque votre charge de travail est exécutée, ainsi que le nombre de requêtes traitées simultanément. Une estimation approximative de la taille de l'instance peut être calculée en multipliant la latence moyenne des requêtes par le nombre de requêtes simultanées. Cela vous donne le nombre moyen de threads simultanés nécessaires pour gérer la charge de travail.

[Chaque vCPU d'une instance Neptune peut prendre en charge deux threads de requête simultanés. En divisant les threads par 2, on obtient le nombre de v CPUs requis, qui peut ensuite être corrélé à la taille d'instance appropriée sur la page de tarification de Neptune.](https://aws.amazon.com/neptune/pricing/) Par exemple :

```
Average Query Latency:         30ms (0.03s)
Number of concurrent queries:  1000/second

Number of threads needed:      0.03 x 1000 = 30 threads
Number of vCPUs needed:        30 / 2 = 15 vCPUs
```

En corrélant cela au nombre de v CPUs dans une instance, nous constatons que nous obtenons une estimation approximative du fait que a `r5.4xlarge` serait l'instance recommandée pour essayer cette charge de travail. Cette estimation est approximative et vise uniquement à fournir des indications initiales sur la sélection de la taille de l'instance. Toute application doit être soumise à un exercice de dimensionnement correct afin de déterminer le nombre et le ou les types d'instances appropriés pour la charge de travail.

Les besoins en mémoire doivent également être pris en compte, ainsi que les exigences de traitement. Neptune est particulièrement performant lorsque les données auxquelles les requêtes accèdent sont disponibles dans le cache du pool de mémoire tampon de la mémoire principale. Le provisionnement d'une mémoire suffisante peut également réduire les I/O coûts de manière significative.

Vous trouverez des informations et des conseils supplémentaires sur le dimensionnement des instances dans un cluster Neptune sur la page [Dimensionnement des instances de base de données dans un cluster de bases de données Neptune](feature-overview-db-clusters.md#feature-overview-sizing-instances).

# Migration des données de Neo4j vers Neptune
<a name="migration-data-migration"></a>

Lorsque vous effectuez une migration de Neo4j vers Amazon Neptune, la migration des données constitue une étape majeure du processus. Plusieurs approches permettent de migrer des données. L'approche appropriée est déterminée par les besoins de l'application, la taille des données et le type de migration souhaité. Cependant, bon nombre de ces migrations nécessitent l'évaluation des mêmes considérations, dont plusieurs sont soulignées ci-dessous.

**Note**  
Consultez la section [Migration d'une base de données de graphes Neo4j vers Neptune à l'aide d'un utilitaire entièrement automatisé](https://aws.amazon.com/blogs/database/migrating-a-neo4j-graph-database-to-amazon-neptune-with-a-fully-automated-utility/) dans le [blog de AWS base](https://aws.amazon.com/blogs/?awsf.blog-master-category=category%23database) de données pour un exemple complet de migration de données hors ligne. step-by-step

## Évaluation de la migration des données de Neo4j vers Neptune
<a name="migration-data-assessment"></a>

Lors de l'évaluation d'une migration de données, la première étape consiste à déterminer la manière dont vous allez migrer les données. Les options dépendent de l'architecture de l'application à migrer, de la taille des données et des besoins de disponibilité pendant la migration. En général, les migrations se répartissent dans l'une des deux catégories suivantes : en ligne ou hors ligne.

Les migrations hors ligne sont généralement les plus simples à réaliser, car l'application n'accepte pas le trafic de lecture ou d'écriture pendant la migration. Une fois que l'application cesse d'accepter le trafic, les données peuvent être exportées, optimisées et importées, et l'application peut être testée avant sa réactivation.

Les migrations en ligne sont plus complexes, car l'application doit continuer à accepter le trafic de lecture et d'écriture pendant la migration des données. Les besoins exacts de chaque migration en ligne peuvent différer, mais l'architecture générale est souvent similaire à la suivante :
+ Un flux des modifications continues apportées à la base de données doit être activé dans Neo4j en configurant [Neo4j Streams comme source pour un cluster Kafka](https://neo4j.com/labs/kafka/4.0/producer/).
+ Une fois cette opération terminée, une exportation du système en cours d'exécution peut être effectuée, en suivant les instructions fournies dans [Exportation de données à partir de Neo4j lors de la migration vers Neptune](#migration-data-exporting), et l'heure peut être consignée pour une corrélation ultérieure avec la rubrique Kafka.
+ Les données exportées sont ensuite importées dans Neptune, en suivant les instructions indiquées dans [Importation de données à partir de Neo4j lors de la migration vers Neptune](#migration-data-importing).
+ Les données modifiées à partir du flux Kafka peuvent ensuite être copiées dans le cluster Neptune à l'aide d'une architecture similaire à celle décrite dans [Writing to Amazon Neptune from Amazon Kinesis Data Streams](https://github.com/aws-samples/amazon-neptune-samples/tree/master/gremlin/stream-2-neptune). Notez que la réplication des modifications peut être exécutée en parallèle pour valider l'architecture et les performances de la nouvelle application.
+ Une fois la migration des données validée, le trafic de l'application peut être redirigé vers le cluster Neptune, et l'instance Neo4j peut être mise hors service.

## Optimisations des modèles de données pour la migration de Neo4j vers Neptune
<a name="migration-data-model-optimization"></a>

Neptune et Neo4j prennent tous deux en charge les graphes de propriétés étiquetés (LPG). Neptune présente toutefois certaines différences d'architecture et de modèle de données dont vous pouvez tirer parti pour optimiser les performances :

### Optimisation du nœud et du bord IDs
<a name="migration-data-node-edge-id-optimization"></a>

Neo4j génère automatiquement une longueur numérique. IDs Avec Cypher, vous pouvez faire référence aux nœuds par ID, mais cela est généralement déconseillé au profit d'une recherche des nœuds en fonction d'une propriété indexée.

Neptune vous permet de [fournir votre propre chaîne pour les sommets et IDs les arêtes](access-graph-gremlin-differences.md#feature-gremlin-differences-user-supplied-ids). Si vous ne fournissez pas les vôtres IDs, Neptune génère automatiquement des représentations sous forme de chaînes UUIDs pour les nouvelles arêtes et sommets.

Si vous migrez des données de Neo4j vers Neptune en les exportant depuis Neo4j puis en les important en masse dans Neptune, vous pouvez conserver celles de Neo4j. IDs Les valeurs numériques générées par Neo4j peuvent être fournies par l'utilisateur lors de l' IDs importation dans Neptune, où elles sont représentées sous forme de chaînes plutôt que de valeurs numériques.

Toutefois, dans certaines circonstances, il peut être utile de convertir une propriété de sommet en ID de sommet. Tout comme la recherche d'un nœud à l'aide d'une propriété indexée est le moyen le plus rapide de trouver un nœud dans Neo4j, la recherche d'un sommet par ID est le moyen le plus rapide de trouver un sommet dans Neptune. Par conséquent, si vous pouvez identifier une propriété de sommet appropriée contenant des valeurs uniques, envisagez de remplacer la valeur \$1id du sommet par la valeur de propriété désignée dans les fichiers CSV de chargement en bloc. Dans ce cas, vous devrez également réécrire les valeurs d'arête \$1from et \$1to correspondantes dans les fichiers CSV.

### Contraintes de schéma lors de la migration de données de Neo4j vers Neptune
<a name="migration-data-schema-constraints"></a>

Dans Neptune, la seule contrainte de schéma disponible est l'unicité de l'ID d'un nœud ou d'une arête. Les applications qui doivent utiliser une contrainte d'unicité sont invitées à envisager cette approche pour obtenir une contrainte d'unicité en spécifiant l'ID du nœud ou de l'arête. Si l'application utilisait plusieurs colonnes comme contrainte d'unicité, l'ID peut être défini sur une combinaison de ces valeurs. Par exemple, `id=123, code='SEA'` peut être représenté par`ID='123_SEA'`) pour obtenir une contrainte d'unicité complexe.

### Optimisation de la direction des arêtes lors de la migration de données de Neo4j vers Neptune
<a name="migration-data-edge-direction"></a>

Lorsque des nœuds, des arêtes ou des propriétés sont ajoutés à Neptune, ils sont automatiquement [indexés de trois manières différentes](feature-overview-storage-indexing.md), avec un quatrième index [facultatif](features-lab-mode.md#features-lab-mode-features-osgp-index). En raison de la façon dont Neptune crée et [utilise les index](feature-overview-storage-indexing.md), les requêtes qui suivent les arêtes sortantes sont plus efficaces que celles qui utilisent des arêtes entrantes. En ce qui concerne le [modèle de stockage de données de graphe](feature-overview-data-model.md) de Neptune, il s'agit de recherches thématiques qui utilisent l'index SPOG.

Si, lors de la migration de votre modèle de données et de vos requêtes vers Neptune, vous constatez que vos requêtes les plus importantes reposent sur la traversée des arêtes entrantes où il existe un fort degré de distribution ramifiée, vous pouvez envisager de modifier votre modèle afin que ces traversées suivent plutôt les arêtes sortantes, en particulier lorsque vous ne pouvez pas spécifier les étiquettes d'arête à traverser. Pour ce faire, inversez la direction des arêtes concernées et mettez à jour les étiquettes des arêtes afin de refléter la sémantique de ce changement de direction. Par exemple, vous pouvez effectuer la modification suivante :

```
person_A — parent_of — person_B
   to:
person_B — child_of — person_A
```

Pour effectuer cette modification dans un [fichier CSV d'arêtes à chargement en bloc](bulk-load-tutorial-format.md), il suffit d'échanger les en-têtes de colonne `~from` et `~to`, et de mettre à jour les valeurs de la colonne `~label`.

Au lieu d'inverser la direction des arêtes, vous pouvez activer un [quatrième index Neptune, l'index OSGP](feature-overview-storage-indexing.md#feature-overview-storage-indexing-osgp), qui rend la traversée des arêtes entrantes (ou les recherches basées sur des objets) beaucoup plus efficace. Cependant, l'activation de ce quatrième index réduit les taux d'insertion et nécessite davantage de stockage.

### Optimisation du filtrage lors de la migration de données de Neo4j vers Neptune
<a name="migration-data-filtering"></a>

Neptune est optimisé pour fonctionner au mieux lorsque les propriétés sont filtrées en fonction de la propriété la plus sélective disponible. Lorsque plusieurs filtres sont utilisés, l'ensemble de résultats correspondants est trouvé pour chacun de ces filtres, puis le chevauchement de tous les ensembles correspondants est calculé. Lorsque cela est possible, la combinaison de plusieurs propriétés en une seule permet de minimiser le nombre de recherches d'index et de réduire la latence d'une requête.

Par exemple, cette requête utilise deux recherches d'index et une jointure :

```
MATCH (n) WHERE n.first_name='John' AND n.last_name='Doe' RETURN n
```

Cette requête récupère les mêmes informations en utilisant une seule recherche d'index :

```
MATCH (n) WHERE n.name='John Doe' RETURN n
```

### 
<a name="migration-data-types"></a>

Neptune prend en charge [différents types de données](bulk-load-tutorial-format-opencypher.md#bulk-load-tutorial-format-opencypher-data-types) que Neo4j.

**Mappages des types de données Neo4j dans les types de données pris en charge par Neptune**
+ **Logique** :   `Boolean`

  Mappez cette valeur dans Neptune avec `Bool` ou `Boolean`.
+ **Numérique** :   `Number`

  Mappez cette valeur dans Neptune avec le type Neptune openCypher suivant le plus proche pouvant prendre en charge toutes les valeurs de la propriété numérique en question :

  ```
    Byte
    Short
    Integer
    Long
    Float
    Double
  ```
+ **Text** :   `String`

  Mappez cette valeur dans Neptune avec `String`.
+ **Point dans le temps** :

  ```
    Date
    Time
    LocalTime
    DateTime
    LocalDateTime
  ```

  Mappez ces éléments dans Neptune avec `Date` au format UTC en utilisant l'un des formats ISO-8601 suivants pris en charge par Neptune :

  ```
    yyyy-MM-dd
    yyyy-MM-ddTHH:mm
    yyyy-MM-ddTHH:mm:ss
    yyyy-MM-ddTHH:mm:ssZ
  ```
+ **Durée** : `Duration`

  Mappez cette valeur dans Neptune avec une valeur numérique pour l'arithmétique des dates, si nécessaire.
+ **Spatial** :   `Point`

  Mappez cette valeur dans Neptune avec les valeurs numériques des composants, chacune d'elles devenant alors une propriété distincte, ou exprimez-la sous forme de valeur de chaîne à interpréter par l'application cliente. Notez que l'intégration de la [recherche en texte intégral](full-text-search.md) de Neptune vous OpenSearch permet d'indexer les propriétés de géolocalisation.

### Migration des propriétés à valeurs multiples de Neo4j vers Neptune
<a name="migration-data-cardinality"></a>

Neo4j permet de stocker des [listes homogènes de types simples](https://neo4j.com/docs/cypher-manual/current/values-and-types/) en tant que propriétés des nœuds et des arêtes. Ces listes peuvent contenir des valeurs en double.

Neptune n'autorise toutefois qu'une [cardinalité définie ou unique](access-graph-gremlin-differences.md#feature-gremlin-differences-vertex-property-cardinality) pour les propriétés des sommets, et une cardinalité unique pour les propriétés des arêtes dans les données des graphes de propriétés. Par conséquent, il n'y a pas de migration directe des propriétés de liste de nœuds Neo4j contenant des valeurs dupliquées vers des propriétés de sommet Neptune ni de migration directe des propriétés de liste de relations Neo4j vers des propriétés d'arête Neptune.

Voici quelques stratégies possibles pour migrer les propriétés des nœuds à valeurs multiples Neo4j avec des valeurs en double dans Neptune :
+ Supprimez les valeurs en double et convertissez la propriété du nœud Neo4j à valeurs multiples en propriété de sommet Neptune à cardinalité définie. Notez que l'ensemble Neptune peut ne pas refléter l'ordre des éléments dans la propriété Neo4j à valeurs multiples d'origine.
+ Convertissez la propriété du nœud Neo4j à valeurs multiples en une représentation sous forme de chaîne d'une liste au format JSON dans une propriété de chaîne de sommet Neptune.
+ Extrayez chacune des valeurs de propriété à valeurs multiples dans un sommet distinct doté d'une propriété de valeur, et connectez ces sommets au sommet parent à l'aide d'une arête portant le nom de la propriété.

De même, les stratégies possibles pour migrer les propriétés des relations Neo4j à valeurs multiples vers Neptune sont les suivantes :
+ Convertissez la propriété de relation Neo4j à valeurs multiples en une représentation sous forme de chaîne d'une liste au format JSON et stockez-la en tant que propriété de chaîne d'arête Neptune.
+ Refactorisez la relation Neo4j en arêtes Neptune entrantes et sortantes attachées à un sommet intermédiaire. Extrayez chacune des valeurs de propriété de relation à valeurs multiples dans un sommet distinct doté d'une propriété de valeur et connectez ces sommets au sommet intermédiaire à l'aide d'une arête portant le nom de la propriété.

Notez qu'une représentation sous forme de chaîne d'une liste au format JSON est opaque pour le langage de requête openCypher, bien qu'openCypher comprenne un prédicat `CONTAINS` qui permet des recherches simples dans des valeurs de chaîne.

## Exportation de données à partir de Neo4j lors de la migration vers Neptune
<a name="migration-data-exporting"></a>

Lorsque vous exportez des données à partir de Neo4j, utilisez les procédures APOC pour les exporter au format [CSV](https://neo4j.com/labs/apoc/4.1/export/csv/) ou [GraphML](https://neo4j.com/labs/apoc/4.1/export/graphml/). Bien qu'il soit possible d'exporter les données dans d'autres formats, il existe des [outils open source](https://github.com/awslabs/amazon-neptune-tools/tree/master/neo4j-to-neptune) pour convertir les données CSV exportées de Neo4j dans le format de chargement en bloc Neptune, ainsi que des [outils open source](https://github.com/awslabs/amazon-neptune-tools/tree/master/graphml2csv) pour convertir les données GraphML exportées de Neo4j dans le format de chargement en bloc Neptune.

Vous pouvez également exporter des données directement dans Amazon S3 à l'aide des différentes procédures APOC. L'exportation vers un compartiment Amazon S3 est désactivée par défaut, mais elle peut être activée à l'aide des procédures décrites dans la section [Exportation dans Amazon S3](https://neo4j.com/labs/apoc/4.3/export/csv/#export-csv-s3-export) dans la documentation APOC de Neo4j.

## Importation de données à partir de Neo4j lors de la migration vers Neptune
<a name="migration-data-importing"></a>

Vous pouvez importer des données dans Neptune en utilisant soit le [chargeur en bloc Neptune](bulk-load.md), soit la logique de l'application dans un langage de requête compatible tel qu'[openCypher](access-graph-opencypher.md).

Le chargeur en bloc Neptune est l'approche préférée pour importer de grandes quantités de données, car il fournit des performances d'importation optimisées si vous suivez les [bonnes pratiques](bulk-load-optimize.md). Le chargeur en bloc prend en charge [deux formats CSV différents](bulk-load-tutorial-format.md), dans lesquels les données exportées à partir de Neo4j peuvent être converties à l'aide des utilitaires open source mentionnés ci-dessus dans la section [Exportation de données](#migration-data-exporting).

Vous pouvez également utiliser openCypher pour importer des données avec une logique personnalisée pour l'analyse, la transformation et l'importation. Vous pouvez envoyer les requêtes openCypher soit via le [point de terminaison HTTPS](access-graph-opencypher-queries.md) (ce qui est recommandé), soit en utilisant le [pilote Bolt](access-graph-opencypher-bolt.md).

# Migration d'une application de Neo4j vers Neptune
<a name="migration-app-migration"></a>

Après avoir migré vos données de Neo4j vers Neptune, l'étape suivante consiste à migrer l'application elle-même. Comme pour les données, plusieurs approches permettent de migrer votre application en fonction des outils que vous utilisez, des exigences, des différences architecturales, etc. Les éléments que vous devez généralement prendre en compte dans ce processus sont décrits ci-dessous.

## Migration des connexions lors du passage de Neo4j à Neptune
<a name="migration-app-connections"></a>

Si vous n'utilisez pas actuellement les pilotes Bolt ou si vous souhaitez utiliser une alternative, vous pouvez vous connecter au [point de terminaison HTTPS](access-graph-opencypher-queries.md) qui fournit un accès complet aux données renvoyées. 

Si vous avez une application qui utilise le [protocole Bolt](access-graph-opencypher-bolt.md), vous pouvez migrer ces connexions vers Neptune et laisser vos applications se connecter avec les mêmes pilotes que dans Neo4j. Pour vous connecter à Neptune, vous devrez peut-être apporter une ou plusieurs des modifications suivantes à votre application :
+ L'URL et le port doivent être mis à jour pour utiliser les points de terminaison et le port du cluster (la valeur par défaut est 8182).
+ Neptune exige que toutes les connexions utilisent le protocole SSL. Vous devez donc spécifier pour chaque connexion qu'elle est chiffrée.
+ Neptune gère l'authentification par le biais de l'[attribution de politiques et de rôles IAM](iam-auth.md). Les politiques et les rôles IAM fournissent un niveau de gestion des utilisateurs extrêmement flexible au sein de l'application. Il est donc important de lire et de comprendre les informations qui se trouvent dans la [présentation d'IAM](iam-auth.md) avant de configurer le cluster.
+ Les connexions Bolt se comportent différemment dans Neptune que dans Neo4j à divers égards, comme expliqué dans [Comportement des connexions Bolt dans Neptune](access-graph-opencypher-bolt.md#access-graph-opencypher-bolt-connections).
+ Vous trouverez plus d'informations et des suggestions dans [Bonnes pratiques Neptune avec openCypher et Bolt](best-practices-opencypher.md).

Il existe des exemples de code pour les langages couramment utilisés tels que Java, Python, .NET et NodeJS, ainsi que pour des scénarios de connexion tels que l'utilisation de l'authentification IAM, dans [Utilisation du protocole Bolt pour envoyer des requêtes openCypher à Neptune](access-graph-opencypher-bolt.md).

## Acheminement des requêtes vers des instances de cluster lors du passage de Neo4j à Neptune
<a name="migration-app-routing"></a>

Les applications clientes Neo4j utilisent un [pilote de routage](https://neo4j.com/docs/driver-manual/1.7/client-applications/#routing_drivers_bolt_routing) et spécifient un [mode d'accès](https://neo4j.com/docs/driver-manual/1.7/sessions-transactions/#driver-transactions-access-mode) pour acheminer les demandes de lecture et d'écriture vers un serveur approprié dans un cluster causal.

Lorsque vous migrez une application cliente vers Neptune, utilisez les [points de terminaison Neptune](feature-overview-endpoints.md) pour acheminer efficacement les requêtes vers une instance appropriée du cluster :
+ Toutes les connexions à Neptune doivent utiliser `bolt://` plutôt que `bolt+routing://` ou `neo4j://` dans l'URL.
+ Le point de terminaison du cluster se connecte à l'instance principale actuelle de votre cluster. Utilisez le point de terminaison du cluster pour acheminer les demandes d'écriture vers l'instance principale.
+ Le point de terminaison du lecteur [distribue les connexions](best-practices-general-basic.md#best-practices-general-loadbalance) entre les instances de réplica en lecture du cluster. Si vous disposez d'un cluster à instance unique sans instance de réplica en lecture, le point de terminaison du lecteur se connecte à l'instance principale, qui prend en charge les opérations d'écriture. Si le cluster contient une ou plusieurs instances de réplica en lecture, l'envoi d'une demande d'écriture au point de terminaison du lecteur génère une exception.
+ Chaque instance du cluster peut également avoir son propre point de terminaison d'instance. Utilisez un point de terminaison d'instance si votre application cliente doit envoyer une demande à une instance spécifique du cluster.

Pour de plus amples informations, veuillez consulter [Considérations relatives aux points de terminaison Neptune](feature-overview-endpoints.md#feature-overview-endpoint-considerations).

## Cohérence des données dans Neptune
<a name="migration-app-consistency"></a>

Lorsque vous utilisez des clusters causaux Neo4j, les réplicas en lecture sont cohérents à terme avec les serveurs principaux, mais les applications clientes peuvent garantir la cohérence causale en utilisant le [chaînage causal](https://neo4j.com/docs/driver-manual/1.7/sessions-transactions/#driver-transactions-causal-chaining). Le chaînage causal implique le transfert de signets entre les transactions, ce qui permet à une application cliente d'écrire sur un serveur principal, puis de lire sa propre écriture à partir d'un réplica en lecture.

Dans Neptune, les instances de réplica en lecture sont cohérents à terme avec l'enregistreur, avec un retard de réplication généralement inférieur à 100 millisecondes. Toutefois, tant qu'une modification n'a pas été répliquée, les mises à jour des arêtes et sommets existants, ainsi que les ajouts d'arêtes et de sommets ne sont pas visibles sur une instance de réplica. Par conséquent, si votre application a besoin d'une cohérence immédiate sur Neptune en lisant chaque écriture, utilisez le point de terminaison du cluster pour l' read-after-writeopération. Il s'agit du seul moment où vous pouvez utiliser le point de terminaison de cluster pour les opérations de lecture. Dans tous les autres cas, utilisez le point de terminaison du lecteur pour les lectures.

## Migration des requêtes de Neo4j vers Neptune
<a name="migration-app-queries"></a>

Bien que la prise en [charge d'openCypher](https://aws.amazon.com/blogs/database/announcing-the-general-availability-of-opencypher-support-for-amazon-neptune/) par Neptune réduise considérablement la quantité de travail requise pour migrer des requêtes à partir de Neo4j, certaines différences restent à évaluer lors de la migration :
+ Comme indiqué dans [Optimisations des modèles de données](migration-data-migration.md#migration-data-model-optimization) ci-dessus, vous devrez peut-être apporter des modifications à votre modèle de données afin de créer un modèle de données de graphe optimisé pour Neptune, ce qui impliquera aussi des modifications de vos requêtes et de vos tests.
+ Neo4j propose une variété d'extensions de langage spécifiques à Cypher, qui ne sont pas incluses dans la spécification openCypher implémentée par Neptune. Selon le cas d'utilisation et la fonctionnalité utilisés, il peut y avoir des solutions de contournement dans le langage openCypher, en utilisant le langage Gremlin ou en utilisant d'autres mécanismes tels que décrits dans [Réécriture des requêtes Cypher pour les exécuter dans openCypher sur Neptune](migration-opencypher-rewrites.md).
+ Les applications utilisent souvent d'autres composants intergiciels pour interagir avec la base de données au lieu des pilotes Bolt eux-mêmes. Vérifiez [Compatibilité de Neptune avec Neo4j](migration-compatibility.md) pour déterminer si les outils ou intergiciels que vous utilisez sont pris en charge.
+ En cas de basculement, le pilote Bolt peut continuer à se connecter à l'instance d'enregistreur ou de lecteur précédente, car le point de terminaison du cluster fourni pour la connexion a été résolu en adresse IP. La gestion appropriée des erreurs dans votre application devrait permettre de résoudre ce problème, comme décrit dans [Création d'une connexion après un basculement](best-practices-opencypher.md#best-practices-opencypher-renew-connection).
+ Lorsque des transactions sont annulées en raison de conflits non résolus ou de délais d'attente de verrouillage, Amazon Neptune répond avec une exception `ConcurrentModificationException`. Pour de plus amples informations, veuillez consulter [Codes d'erreur du moteur](errors-engine-codes.md). En tant que bonne pratique, les clients doivent toujours intercepter et gérer ces exceptions.

  Une exception `ConcurrentModificationException` se produit parfois lorsque plusieurs threads ou plusieurs applications écrivent simultanément sur le système. En raison des [niveaux d'isolement des transactions](transactions-neptune.md#transactions-neptune-mutation), ces conflits sont parfois inévitables.
+ Neptune prend en charge l'exécution des requêtes Gremlin et openCypher au niveau des mêmes données. En d'autres termes, dans certains scénarios, vous devrez peut-être envisager d'utiliser Gremlin, avec ses fonctionnalités de requête plus puissantes, pour exécuter certaines des fonctionnalités de vos requêtes.

Comme indiqué dans [Provisionnement de l'infrastructure](migration-provisioning-infrastructure.md) ci-dessus, chaque application doit être soumise à un exercice de dimensionnement correct afin de garantir que le nombre d'instances, la taille des instances et la topologie du cluster sont tous optimisés pour la charge de travail spécifique de l'application.

Les considérations abordées ici pour la migration de votre application sont les plus courantes, mais cette liste n'est pas exhaustive. Chaque application est unique. N'hésitez pas à contacter l'équipe AWS chargée de votre compte ou à contacter l'équipe chargée de votre compte si vous avez d'autres questions.

## Fonctionnalités et outils de migration spécifiques à Neo4j
<a name="migration-app-neo4j-specific"></a>

Neo4j possède une variété de fonctionnalités personnalisées et de modules complémentaires avec des fonctionnalités sur lesquelles votre application peut s'appuyer. Lors de l'évaluation de la nécessité de migrer cette fonctionnalité, il est souvent utile de déterminer s'il existe une meilleure approche AWS pour atteindre le même objectif. [Compte tenu des [différences architecturales entre Neo4j et Neptune](migration-architectural-differences.md), vous pouvez souvent trouver des alternatives efficaces qui tirent parti d'autres AWS services ou intégrations.](integrations.md)

Consultez [Compatibilité de Neptune avec Neo4j](migration-compatibility.md) pour obtenir la liste des fonctionnalités spécifiques à Neo4J et des solutions de contournement suggérées.

# Compatibilité de Neptune avec Neo4j
<a name="migration-compatibility"></a>

Neo4j adopte une approche all-in-one architecturale, dans laquelle le chargement des données, l'ETL des données, les requêtes d'application, le stockage des données et les opérations de gestion se produisent tous dans le même ensemble de ressources de calcul, telles que EC2 les instances. Amazon Neptune est une base de données orientée graphe avec des spécifications ouvertes et axée sur l'OLTP. Son architecture sépare les opérations et dissocie les ressources afin qu'elles puissent se mettre à l'échelle de manière dynamique.

Neo4j contient une variété de fonctionnalités et d'outils, y compris des outils tiers, qui ne font pas partie de la spécification openCypher, qui sont incompatibles avec openCypher ou qui sont incompatibles avec l'implémentation Neptune d'openCypher. Vous trouverez ci-dessous une liste des plus courants.

## Fonctionnalités spécifiques à Neo4J qui ne se trouvent pas dans Neptune
<a name="migration-compatibility-features"></a>
+ **`LOAD CSV`** : Neptune a une approche architecturale différente de celle de Neo4j pour charger les données. Pour permettre une meilleure mise à l'échelle et une meilleure optimisation des coûts, Neptune met en œuvre une séparation des problèmes relatifs aux ressources et recommande d'utiliser l'une des [intégrations de services AWS](integrations.md) (par exemple, AWS Glue ) afin d'exécuter les processus ETL requis pour préparer les données dans un [format](bulk-load-tutorial-format.md) pris en charge par le [chargeur en bloc Neptune](bulk-load.md).

  Une autre option consiste à faire la même chose en utilisant du code d'application exécuté sur des ressources de AWS calcul telles que les EC2 instances Amazon, les fonctions Lambda, Amazon Elastic Container Service, les AWS Batch tâches, etc. Le code peut utiliser le [point de terminaison HTTPS](access-graph-opencypher-queries.md) de Neptune ou le [point de terminaison Bolt](access-graph-opencypher-bolt.md).
+ **Contrôle d'accès précis** : Neptune prend en charge le contrôle d'accès granulaire des actions d'accès aux données à l'aide de [clés de condition IAM](iam-data-access-policies.md). Un contrôle d'accès précis supplémentaire peut être mis en œuvre au niveau de la couche application.
+ **Neo4j Fabric** : Neptune prend en charge la fédération de requêtes entre les bases de données pour les charges de travail RDF à l'aide du mot clé SPARQL [`SERVICE`](sparql-service.md). Comme il n'existe pas actuellement de norme ou de spécification ouverte pour la fédération de requêtes pour les charges de travail des graphes de propriétés, cette fonctionnalité devrait être implémentée au niveau de la couche application.
+ **Contrôle d'accès basé sur les rôles (RBAC)** : [Neptune gère l'authentification en attribuant des politiques et des rôles IAM](iam-auth.md). Les politiques et les rôles IAM fournissent un niveau de gestion des utilisateurs extrêmement flexible au sein d'une application. Il est donc utile de lire et de comprendre les informations qui se trouvent dans la [présentation d'IAM](iam-auth.md) avant de configurer le cluster.

  
+ **Signets** : les clusters Neptune se composent d'une seule instance d'enregistreur et de jusqu'à 15 instances de réplica en lecture. Les données écrites dans l'instance d'enregistreur sont conformes à la norme ACID et offrent une solide garantie de cohérence lors des lectures ultérieures. Les réplicas en lecture utilisent le même volume de stockage que l'instance d'enregistreur et sont cohérentes à terme, généralement en moins de 100 ms à partir du moment où les données sont écrites. Si votre cas d'utilisation nécessite immédiatement de garantir la cohérence de lecture des nouvelles écritures, ces lectures doivent être dirigées vers le point de terminaison du cluster plutôt que vers le point de terminaison du lecteur.
+ **Procédures APOC**  étant donné que les procédures APOC ne sont pas incluses dans la spécification openCypher, Neptune ne fournit pas de prise en charge directe pour les procédures externes. Neptune s'appuie plutôt sur [des intégrations avec d'autres AWS services](integrations.md) pour obtenir des fonctionnalités similaires pour les utilisateurs finaux de manière évolutive, sécurisée et robuste. Parfois, les procédures APOC peuvent être réécrites dans openCypher ou Gremlin, et certaines ne sont pas pertinentes pour les applications Neptune.

  En général, les procédures APOC entrent dans les catégories ci-dessous :
  + **[Importation](https://neo4j.com/labs/apoc/4.2/import/)** : Neptune prend en charge l'importation de données dans divers formats à l'aide de langages de requête, du [chargeur en bloc Neptune](bulk-load.md) ou en tant que cible d'[AWS Database Migration Service](dms-neptune.md). Les opérations ETL sur les données peuvent être effectuées à AWS Glue l'aide du package [https://github.com/awslabs/amazon-neptune-tools/tree/master/neptune-python-utils](https://github.com/awslabs/amazon-neptune-tools/tree/master/neptune-python-utils)open source.
  + **[Exportation](https://neo4j.com/labs/apoc/4.2/export/)** : Neptune prend en charge l'exportation de données à l'aide de l'utilitaire [`neptune-export`](neptune-data-export.md), qui accepte une variété de formats et de méthodes d'exportation courants.
  + **[Intégration de base de données](https://neo4j.com/labs/apoc/4.2/database-integration/)** — Neptune prend en charge l'intégration avec d'autres bases de données à l'aide d'outils ETL tels que AWS Glue ou d'outils de migration tels que. [AWS Database Migration Service](dms-neptune.md)
  + **[Mises à jour des graphes](https://neo4j.com/labs/apoc/4.2/graph-updates/)** : Neptune propose un ensemble complet de fonctionnalités permettant de mettre à jour les données des graphes de propriétés grâce à sa prise en charge des langages de requête openCypher et Gremlin. Consultez [Réécritures Cypher](migration-opencypher-rewrites.md) pour obtenir des exemples de réécritures de procédures couramment utilisées.
  + **[Structures de données](https://neo4j.com/labs/apoc/4.2/data-structures/)** : Neptune propose un ensemble complet de fonctionnalités permettant de mettre à jour les données des graphes de propriétés grâce à sa prise en charge des langages de requête openCypher et Gremlin. Consultez [Réécritures Cypher](migration-opencypher-rewrites.md) pour obtenir des exemples de réécritures de procédures couramment utilisées.
  + **[Temporel (date et heure)](https://neo4j.com/labs/apoc/4.2/temporal/)** : Neptune propose un ensemble complet de fonctionnalités pour mettre à jour les données du graphe de propriétés grâce à sa prise en charge des langages de requête openCypher et Gremlin. Consultez [Réécritures Cypher](migration-opencypher-rewrites.md) pour obtenir des exemples de réécritures de procédures couramment utilisées.
  + **[Mathématique](https://neo4j.com/labs/apoc/4.2/mathematical/)** : Neptune propose un ensemble complet de fonctionnalités permettant de mettre à jour les données des graphes de propriétés grâce à sa prise en charge des langages de requête openCypher et Gremlin. Consultez [Réécritures Cypher](migration-opencypher-rewrites.md) pour obtenir des exemples de réécritures de procédures couramment utilisées.
  + **[Requête de graphe avancée](https://neo4j.com/labs/apoc/4.2/graph-querying/)** : Neptune propose un ensemble complet de fonctionnalités pour mettre à jour les données des graphes de propriétés grâce à sa prise en charge des langages de requête openCypher et Gremlin. Consultez [Réécritures Cypher](migration-opencypher-rewrites.md) pour obtenir des exemples de réécritures de procédures couramment utilisées.
  + **[Comparaison de graphes](https://neo4j.com/labs/apoc/4.2/comparing-graphs/)** : Neptune propose un ensemble complet de fonctionnalités pour mettre à jour les données des graphes de propriétés grâce à sa prise en charge des langages de requête openCypher et Gremlin. Consultez [Réécritures Cypher](migration-opencypher-rewrites.md) pour obtenir des exemples de réécritures de procédures couramment utilisées.
  + **[Exécution Cypher](https://neo4j.com/labs/apoc/4.2/cypher-execution/)** : Neptune prend en charge un ensemble complet de fonctionnalités pour mettre à jour les données du graphe de propriétés grâce à sa prise en charge des langages de requête openCypher et Gremlin. Consultez [Réécritures Cypher](migration-opencypher-rewrites.md) pour obtenir des exemples de réécritures de procédures couramment utilisées.
+ **Procédures personnalisées** : Neptune ne prend pas en charge les procédures personnalisées créées par les utilisateurs. Cette fonctionnalité devrait être implémentée au niveau de la couche application.
+ **Géospatiale** — Bien que Neptune ne fournisse pas de support natif pour les fonctionnalités géospatiales, des fonctionnalités similaires peuvent être obtenues grâce à l'intégration à AWS d'autres services, comme le montre ce billet de blog : Combinez [Amazon Neptune et OpenSearch Amazon Service pour les requêtes géospatiales de Ross Gabay et](https://aws.amazon.com/blogs/database/combine-amazon-neptune-and-amazon-opensearch-service-for-geospatial-queries/) Abhilash Vinod (1er février 2022).
+ **Science des données graphiques** : Neptune prend aujourd’hui en charge l’analyse de graphes par le biais de [Neptune Analytics](https://docs.aws.amazon.com/neptune-analytics/latest/userguide/what-is-neptune-analytics.html), un moteur optimisé pour la mémoire qui prend en charge une bibliothèque d’algorithmes d’analyse de graphes.

  Neptune propose aussi une intégration avec le [kit SDK AWS Pandas](https://github.com/amazon-archives/fully-automated-neo4j-to-neptune) et plusieurs [exemples de blocs-notes](https://github.com/aws/graph-notebook/tree/main/src/graph_notebook/notebooks/05-Data-Science) qui montrent comment tirer parti de cette intégration dans les environnements Python pour exécuter des analyses sur des données de graphe.

  
+ **Contraintes de schéma** : dans Neptune, la seule contrainte de schéma disponible est l'unicité de l'ID d'un nœud ou d'une arête. Aucune fonctionnalité ne permet de spécifier d'autres contraintes de schéma ni de contraintes d'unicité ou de valeur supplémentaires sur un élément du graphe. Les valeurs d'ID dans Neptune sont des chaînes et peuvent être définies à l'aide de Gremlin, comme ceci :

  ```
  g.addV('person').property(id, '1') )
  ```

  Les applications qui doivent utiliser l'ID comme contrainte d'unicité sont encouragées à essayer cette approche pour obtenir une contrainte d'unicité. Si l'application utilisait plusieurs colonnes comme contrainte d'unicité, l'ID peut être défini sur une combinaison de ces valeurs. Par exemple, `id=123, code='SEA'` pourrait être représenté comme `ID='123_SEA'` pour obtenir une contrainte d'unicité complexe.
+ **Architecture mutualisée** : Neptune ne prend en charge qu'un seul graphe par cluster. Pour créer un système multilocataire à l'aide de Neptune, utilisez plusieurs clusters ou partitionnez logiquement les locataires au sein d'un seul graphe et appliquez la séparation avec la logique côté application. Par exemple, ajoutez une propriété `tenantId` et incluez-la dans chaque requête, comme suit :

  ```
  MATCH p=(n {tenantId:1})-[]->({tenantId:1}) RETURN p LIMIT 5)
  ```

  [Neptune sans serveur](neptune-serverless.md) facilite la mise en œuvre de l'architecture mutualisée à l'aide de plusieurs clusters de bases de données, chacun étant mis à l'échelle indépendamment et automatiquement selon les besoins.

## Prise en charge de Neptune pour les outils Neo4j
<a name="migration-compatibility-tools"></a>

Neptune propose les alternatives suivantes aux outils Neo4j :
+ **[Navigateur Neo4j](https://neo4j.com/docs/operations-manual/current/installation/neo4j-browser/)** : Neptune offre des [blocs-notes de graphe](graph-notebooks.md) open source qui fournissent un IDE axé sur les développeurs pour exécuter des requêtes et visualiser les résultats.
+ **[Neo4j Bloom](https://neo4j.com/product/bloom/)** : Neptune prend en charge les visualisations de graphe enrichies à l'aide de [solutions de visualisation tierces](visualization-tools.md) telles que Graph-explorer, Tom Sawyer, Cambridge Intelligence, Graphistry, metaphacts et G.V().
+ **[GraphQL —](https://graphql.org/)** Neptune prend actuellement en charge GraphQL par le biais d'intégrations personnalisées. AWS AppSync Consultez le billet de blog [Build a graph application with Amazon Neptune and AWS Amplify](https://aws.amazon.com/blogs/database/build-a-graph-application-with-amazon-neptune-and-aws-amplify/), et l'exemple de projet intitulé [Building Serverless Calorie Tracker application with and](https://github.com/aws-samples/aws-appsync-calorie-tracker-workshop) Amazon Neptune. AWS AppSync 
+ **[NeoSemantics](https://neo4j.com/labs/neosemantics/4.0/)**— Neptune prend en charge le modèle de données RDF de manière native. Il est donc conseillé aux clients souhaitant exécuter des charges de travail RDF d'utiliser le support du modèle RDF de Neptune.
+ **[Arrows.app](https://arrows.app/)** : le chiffrement créé lors de l'exportation du modèle à l'aide de la commande d'exportation est compatible avec Neptune.
+ **[Linkurious Ogma](https://doc.linkurious.com/ogma/latest/)** : un exemple d'intégration avec Linkurious Ogma est [disponible ici](https://github.com/aws-samples/amazon-neptune-samples/tree/master/gremlin/ogma-neptune).
+ **[Spring Data Neo4j](https://spring.io/projects/spring-data-neo4j)** : n'est actuellement pas compatible avec Neptune.
+ **[Connecteur Neo4j Spark](https://neo4j.com/docs/spark/current/)** : le connecteur Neo4j Spark peut être utilisé dans une tâche Spark pour se connecter à Neptune à l'aide d'openCypher. Voici un exemple de code et un exemple de configuration d'application :

  **Exemple de code :**

  ```
  SparkSession spark = SparkSession
              .builder()
              .config("encryption.enabled", "true")
              .appName("Simple Application").config("spark.master", "local").getOrCreate();
  
  Dataset<Row> df = spark.read().format("org.neo4j.spark.DataSource")
              .option("url", "bolt://(your cluster endpoint):8182")
              .option("encryption.enabled", "true")
              .option("query", "MATCH (n:airport) RETURN n")
              .load();
              
  System.out.println("TOTAL RECORD COUNT: " + df.count());
  spark.stop();
  ```

  **Configuration de l'application :**

  ```
  <dependency>
      <groupId>org.neo4j</groupId>
      <artifactId>neo4j-connector-apache-spark_2.12-4.1.0</artifactId>
      <version>4.0.1_for_spark_3</version>
  </dependency>
  ```

### Fonctionnalités et outils Neo4j non répertoriés ici
<a name="migration-compatibility-tools-unlisted"></a>

Si vous utilisez un outil ou une fonctionnalité qui n'est pas répertorié ici, nous ne sommes pas certains de sa compatibilité avec Neptune ou les autres services qu'il propose. AWS N'hésitez pas à contacter l'équipe AWS chargée de votre compte ou à contacter l'équipe chargée de votre compte si vous avez d'autres questions.

# Réécriture des requêtes Cypher pour les exécuter dans openCypher sur Neptune
<a name="migration-opencypher-rewrites"></a>

Le langage openCypher est un langage de requête déclaratif pour les graphes de propriétés initialement développé par Neo4j, puis rendu open source en 2015. Il a contribué au [projet openCypher](https://www.opencypher.org/) sous une licence open source Apache 2. Chez AWS, nous pensons que l'open source est bénéfique pour tout le monde et nous nous engageons à apporter la valeur de l'open source à nos clients et l'excellence opérationnelle AWS aux communautés open source.

OpenCypher la syntaxe est documentée dans le [Cypher Query Language Reference, version 9](https://s3.amazonaws.com/artifacts.opencypher.org/openCypher9.pdf).

Comme openCypher contient un sous-ensemble de la syntaxe et des fonctionnalités du langage de requête Cypher, certains scénarios de migration nécessitent soit de réécrire les requêtes dans des formulaires compatibles avec openCypher, soit d'examiner d'autres méthodes pour obtenir le fonctionnement souhaité.

Cette section contient des recommandations pour gérer les différences courantes, mais elles ne sont en aucun cas exhaustives. Testez minutieusement toute application utilisant ces réécritures pour vous assurer que les résultats sont conformes à vos attentes.

## Réécriture des fonctions de prédicat `None`, `All` et `Any`
<a name="migration-opencypher-rewrites-none-all-any"></a>

Ces fonctions ne font pas partie de la spécification openCypher. Des résultats comparables peuvent être obtenus dans openCypher à l'aide de la compréhension de liste.

Par exemple, recherchez tous les chemins qui vont d'un nœud `Start` au nœud `End`, mais aucun trajet n'est autorisé à passer par un nœud dont la propriété de classe correspond à `D` :

```
# Neo4J Cypher code
match p=(a:Start)-[:HOP*1..]->(z:End)
where none(node IN nodes(p) where node.class ='D')
return p

# Neptune openCypher code
match p=(a:Start)-[:HOP*1..]->(z:End)
where size([node IN nodes(p) where node.class = 'D']) = 0
return p
```

La compréhension de liste peut obtenir ces résultats comme suit :

```
all  => size(list_comprehension(list)) = size(list)
any  => size(list_comprehension(list)) >= 1
none => size(list_comprehension(list)) = 0
```

## Réécriture de la fonction Cypher `reduce()` en openCypher
<a name="migration-opencypher-rewrites-reduce"></a>

La fonction `reduce()` ne fait pas partie de la spécification openCypher. Elle est souvent utilisée pour créer une agrégation de données à partir d'éléments d'une liste. Dans de nombreux cas, vous pouvez utiliser une combinaison de la compréhension de liste et de la clause `UNWIND` pour obtenir des résultats similaires.

Par exemple, la requête Cypher suivante trouve tous les aéroports situés sur des trajets comportant un à trois arrêts entre Anchorage (ANC) et Austin (AUS), et renvoie la distance totale de chaque trajet :

```
MATCH p=(a:airport {code: 'ANC'})-[r:route*1..3]->(z:airport {code: 'AUS'})
RETURN p, reduce(totalDist=0, r in relationships(p) | totalDist + r.dist) AS totalDist
ORDER BY totalDist LIMIT 5
```

Vous pouvez écrire la même requête en openCypher pour Neptune comme suit :

```
MATCH p=(a:airport {code: 'ANC'})-[r:route*1..3]->(z:airport {code: 'AUS'})
UNWIND [i in relationships(p) | i.dist] AS di
RETURN p, sum(di) AS totalDist
ORDER BY totalDist
LIMIT 5
```

## Réécriture de la clause Cypher FOREACH en openCypher
<a name="migration-opencypher-rewrites-foreach"></a>

La clause FOREACH ne fait pas partie de la spécification openCypher. Elle est souvent utilisée pour mettre à jour les données au milieu d'une requête, souvent à partir d'agrégations ou d'éléments au sein d'un chemin.

À titre d'exemple, recherchez tous les aéroports situés sur un trajet ne comportant pas plus de deux arrêts entre Anchorage (ANC) et Austin (AUS) et définissez la propriété « visited » pour chacun d'eux :

```
# Neo4J Example
MATCH p=(:airport {code: 'ANC'})-[*1..2]->({code: 'AUS'})
FOREACH (n IN nodes(p) | SET n.visited = true)

# Neptune openCypher
MATCH p=(:airport {code: 'ANC'})-[*1..2]->({code: 'AUS'})
WITH nodes(p) as airports
UNWIND airports as a
SET a.visited=true
```

Voici un autre exemple :

```
# Neo4J Example
MATCH p=(start)-[*]->(finish)
WHERE start.name = 'A' AND finish.name = 'D'
FOREACH (n IN nodes(p) | SET n.marked = true)

# Neptune openCypher
MATCH p=(start)-[*]->(finish)
WHERE start.name = 'A' AND finish.name = 'D'
UNWIND nodes(p) AS n
SET n.marked = true
```

## Réécriture des procédures Neo4j APOC dans Neptune
<a name="migration-opencypher-rewrites-apoc"></a>

Les exemples ci-dessous utilisent openCypher pour remplacer certaines des [procédures APOC](https://neo4j.com/blog/intro-user-defined-procedures-apoc/) les plus couramment utilisées. Ces exemples sont fournis à titre de référence uniquement et visent à fournir des suggestions sur la manière de gérer les scénarios courants. Dans la pratique, chaque application est différente. Vous devrez donc élaborer vos propres stratégies pour fournir toutes les fonctionnalités dont vous avez besoin.

### Réécriture des procédures `apoc.export`
<a name="migration-opencypher-rewrites-apoc-export"></a>

Neptune propose un éventail d'options pour les exportations de graphes complets et les exportations basées sur des requêtes dans différents formats de sortie tels que CSV et JSON, à l'aide de l'utilitaire [neptune-export](https://github.com/aws/neptune-export) (voir [Exportation de données depuis un cluster de bases de données Neptune](neptune-data-export.md)).

### Réécriture des procédures `apoc.schema`
<a name="migration-opencypher-rewrites-apoc-schema"></a>

Neptune n'a pas de schéma, d'index ni de contraintes explicitement définis. De nombreuses procédures `apoc.schema` ne sont donc plus nécessaires. Voici quelques exemples :
+ `apoc.schema.assert`
+ `apoc.schema.node.constraintExists`
+ `apoc.schema.node.indexExists`,
+ `apoc.schema.relationship.constraintExists`
+ `apoc.schema.relationship.indexExists`
+ `apoc.schema.nodes`
+ `apoc.schema.relationships`

Neptune openCypher prend en charge la récupération de valeurs similaires à celles des procédures, comme indiqué ci-dessous. Toutefois, il peut rencontrer des problèmes de performances sur les graphes de grande taille, car l'analyse d'une grande partie du graphe est nécessaire pour pouvoir renvoyer la réponse.

```
# openCypher replacement for apoc.schema.properties.distinct
MATCH (n:airport)
RETURN DISTINCT n.runways
```

```
# openCypher replacement for apoc.schema.properties.distinctCount
MATCH (n:airport)
RETURN DISTINCT n.runways, count(n.runways)
```

### Alternatives aux procédures `apoc.do`
<a name="migration-opencypher-rewrites-apoc-do"></a>

Ces procédures sont utilisées pour fournir une exécution de requête conditionnelle facile à implémenter à l'aide d'autres clauses openCypher. Dans Neptune, il existe au moins deux manières d'obtenir un comportement similaire :
+ L'une des solutions consiste à combiner les fonctionnalités de compréhension de liste openCypher avec la clause `UNWIND`.
+ Une autre méthode consiste à utiliser les étapes choose() et coalesce() dans Gremlin.

Des exemples de ces approches sont présentés ci-dessous.

#### Alternatives à apoc.do.when
<a name="migration-opencypher-rewrites-apoc-do-when"></a>

```
# Neo4J Example
MATCH (n:airport {region: 'US-AK'})
CALL apoc.do.when(
 n.runways>=3,
 'SET n.is_large_airport=true RETURN n',
 'SET n.is_large_airport=false RETURN n',
 {n:n}
) YIELD value
WITH collect(value.n) as airports
RETURN size([a in airports where a.is_large_airport]) as large_airport_count,
size([a in airports where NOT a.is_large_airport]) as small_airport_count


# Neptune openCypher
MATCH (n:airport {region: 'US-AK'})
WITH n.region as region, collect(n) as airports
WITH [a IN airports where a.runways >= 3] as large_airports,
[a IN airports where a.runways < 3] as small_airports, airports
UNWIND large_airports as la
SET la.is_large_airport=true
WITH DISTINCT small_airports, airports
UNWIND small_airports as la
    SET la.small_airports=true
WITH DISTINCT airports
RETURN size([a in airports where a.is_large_airport]) as large_airport_count,
size([a in airports where NOT a.is_large_airport]) as small_airport_count

#Neptune Gremlin using choose()
g.V().
  has('airport', 'region', 'US-AK').
  choose(
    values('runways').is(lt(3)),
    property(single, 'is_large_airport', false),
    property(single, 'is_large_airport', true)).
  fold().
  project('large_airport_count', 'small_airport_count').
    by(unfold().has('is_large_airport', true).count()).
    by(unfold().has('is_large_airport', false).count())

 #Neptune Gremlin using coalesce() 
g.V().
  has('airport', 'region', 'US-AK').
  coalesce(
    where(values('runways').is(lt(3))).
    property(single, 'is_large_airport', false),
    property(single, 'is_large_airport', true)).
  fold().
  project('large_airport_count', 'small_airport_count').
    by(unfold().has('is_large_airport', true).count()).
    by(unfold().has('is_large_airport', false).count())
```

#### Alternatives à apoc.do.case
<a name="migration-opencypher-rewrites-apoc-do-case"></a>

```
# Neo4J Example
MATCH (n:airport {region: 'US-AK'})
CALL apoc.case([
 n.runways=1, 'RETURN "Has one runway" as b',
 n.runways=2, 'RETURN "Has two runways" as b'
 ],
 'RETURN "Has more than 2 runways" as b'
) YIELD value 
RETURN {type: value.b,airport: n}

# Neptune openCypher
MATCH (n:airport {region: 'US-AK'})
WITH n.region as region, collect(n) as airports
WITH [a IN airports where a.runways =1] as single_runway,
[a IN airports where a.runways =2] as double_runway,
[a IN airports where a.runways >2] as many_runway
UNWIND single_runway as sr
    WITH {type: "Has one runway",airport: sr} as res, double_runway, many_runway
WITH DISTINCT double_runway as double_runway, collect(res) as res, many_runway
UNWIND double_runway as dr
    WITH {type: "Has two runways",airport: dr} as two_runways, res, many_runway
WITH collect(two_runways)+res as res, many_runway
UNWIND many_runway as mr
    WITH {type: "Has more than 2 runways",airport: mr} as res2, res, many_runway
WITH collect(res2)+res as res
UNWIND res as r
RETURN r

#Neptune Gremlin using choose()
g.V().
  has('airport', 'region', 'US-AK').
  project('type', 'airport').
    by(
      choose(values('runways')).
        option(1, constant("Has one runway")).
        option(2, constant("Has two runways")).
        option(none, constant("Has more than 2 runways"))).
    by(elementMap())

 #Neptune Gremlin using coalesce()
 g.V().
  has('airport', 'region', 'US-AK').
  project('type', 'airport').
    by(
      coalesce(
        has('runways', 1).constant("Has one runway"),
        has('runways', 2).constant("Has two runways"),
        constant("Has more than 2 runways"))).
    by(elementMap())
```

## Alternatives aux propriétés basées sur des listes
<a name="migration-opencypher-rewrites-lists"></a>

Neptune ne prend actuellement pas en charge le stockage des propriétés basées sur des listes. Cependant, des résultats similaires peuvent être obtenus en stockant les valeurs de liste sous forme de chaîne séparée par des virgules, puis en utilisant les fonctions `join()` et `split()` pour construire et déconstruire la propriété de liste.

Par exemple, si nous voulions enregistrer une liste de balises en tant que propriété, nous pourrions utiliser l'exemple de réécriture qui montre comment récupérer une propriété séparée par des virgules, puis utiliser les fonctions `split()` et `join()` avec la compréhension de liste pour obtenir des résultats comparables :

```
# Neo4j Example (In this example, tags is a durable list of string.
MATCH (person:person {name: "TeeMan"})
WITH person, [tag in person.tags WHERE NOT (tag IN ['test1', 'test2', 'test3'])] AS newTags
SET person.tags = newTags
RETURN person

# Neptune openCypher 
MATCH (person:person {name: "TeeMan"})
WITH person, [tag in split(person.tags, ',') WHERE NOT (tag IN ['test1', 'test2', 'test3'])] AS newTags
SET person.tags = join(newTags,',')
RETURN person
```

## Réécriture des sous-requêtes CALL
<a name="migration-opencypher-rewrites-call-subqueries"></a>

 `CALL`Les sous-requêtes Neptune ne prennent pas en charge la syntaxe `CALL (friend) { ... }` permettant d'importer des variables dans le champ d'application de la sous-requête (dans cet `friend` exemple). Veuillez utiliser la `WITH` clause contenue dans la sous-requête pour la même chose, par exemple, `CALL { WITH friend ... }` 

 Les `CALL` sous-requêtes facultatives ne sont pas prises en charge pour le moment. 

## Autres différences entre Neptune openCypher et Cypher
<a name="opencypher-compliance-other-differences"></a>
+ Neptune prend uniquement en charge les connexions TCP pour le protocole Bolt. WebSocketsles connexions pour Bolt ne sont pas prises en charge.
+ Neptune openCypher supprime les espaces tels que définis par Unicode dans les fonctions `trim()`, `ltrim()` et `rtrim()`.
+ Dans Neptune openCypher, `tostring(`double`)` ne passe pas automatiquement en notation E pour les grandes valeurs du double.

# Ressources pour la migration de Neo4j vers Neptune
<a name="migration-resources"></a>

Neptune fournit plusieurs outils et ressources qui peuvent faciliter le processus de migration.

**Outils pour faciliter la migration de Neo4j vers Neptune**
+ L'OpenCypher. [CheatSheet](https://github.com/aws-samples/amazon-neptune-samples/blob/master/opencypher/Cheatsheet.md)
+ [neo4 j-to-neptune](https://github.com/awslabs/amazon-neptune-tools/tree/master/neo4j-to-neptune) — Un utilitaire en ligne de commande pour migrer des données de Neo4j vers Neptune. Cet outil permet notamment de :
  + Exportez les données d'un graphe Neo4j correctement configuré.
  + Convertissez ces données au format Neptune.
  + Chargez ces données en masse dans Neptune.
  + Effectuez certaines conversions de base des données lors de la conversion au format Neptune, par exemple en renommant les étiquettes des sommets ou des arêtes et en générant des éléments.
  + Générez des propriétés pour les nœuds et les arêtes à l'aide de modèles (par exemple, créez une `~id` valeur à l'aide d'un modèle, comme `Person_{personid}` dans les situations où vous devez créer l'identifiant unique d'un élément).
+ [Vérificateur de compatibilité des requêtes OpenCypher](https://github.com/awslabs/amazon-neptune-tools/tree/master/opencypher-compatability-checker) — Cet outil prend en compte les requêtes OpenCypher et va :
  + Vérifiez la compatibilité avec la version sélectionnée de Neptune.
  + Identifiez les fonctions et clauses spécifiques non prises en charge avec leurs positions.
  + Suggérez des remplacements si disponibles.
  + Fournissez une description de toute autre erreur de syntaxe.