

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Migración de Neo4j a Amazon Neptune
<a name="migrating-from-neo4j"></a>

Tanto Neo4j como Amazon Neptune son bases de datos de gráficos, diseñadas para cargas de trabajo de gráficos transaccionales en línea que admiten el modelo de datos de gráficos de propiedades etiquetadas. Estas similitudes hacen de Neptune una opción común para los clientes que buscan migrar sus aplicaciones de Neo4j actuales. Sin embargo, estas migraciones no son simples procesos de migrar mediante lift-and-shift, ya que existen diferencias en cuanto a la compatibilidad con los lenguajes y las características, las características operativas, la arquitectura de los servidores y las capacidades de almacenamiento entre las dos bases de datos.

En esta página se explica el proceso de migración y se presentan aspectos a tener en cuenta antes de migrar una aplicación de gráficos de Neo4j a Neptune. Estos aspectos suelen aplicarse a cualquier aplicación de gráficos de Neo4j, ya sea que funcione con una base de datos Community, Enterprise o Aura. Aunque cada solución sea única y pueda requerir procedimientos adicionales, todas las migraciones siguen el mismo patrón general.

Cada uno de los pasos descritos en las siguientes secciones incluye aspectos a tener en cuenta y recomendaciones para simplificar el proceso de migración. Además, hay [herramientas de código abierto y publicaciones de blog](migration-resources.md) que describen el proceso, así como una [sección de compatibilidad de características](migration-compatibility.md) con opciones arquitectónicas recomendadas.

**Topics**
+ [Información general sobre la migración de Neo4j a Neptune](migrating-from-neo4j-general.md)
+ [Preparación para migrar de Neo4j a Neptune](preparing-to-migrate-from-neo4j.md)
+ [Aprovisionamiento de la infraestructura al migrar de Neo4j a Neptune](migration-provisioning-infrastructure.md)
+ [Migración de datos de Neo4j a Neptune](migration-data-migration.md)
+ [Migración de aplicaciones de Neo4j a Neptune](migration-app-migration.md)
+ [Compatibilidad de Neptune con Neo4j](migration-compatibility.md)
+ [Reescritura de consultas de Cypher para ejecutarlas en openCypher en Neptune](migration-opencypher-rewrites.md)
+ [Recursos para migrar de Neo4j a Neptune](migration-resources.md)

# Información general sobre la migración de Neo4j a Neptune
<a name="migrating-from-neo4j-general"></a>

Con la [compatibilidad de Neptune con el lenguaje de consulta de openCypher](feature-opencypher-compliance.md), puede mover la mayoría de las cargas de trabajo de Neo4j que utilizan el protocolo Bolt o HTTPS a Neptune. Sin embargo, openCypher es una especificación de código abierto que incluye la mayoría de las funciones compatibles con otras bases de datos, como Neo4j, aunque no todas.

A pesar de ser compatible en muchos aspectos, Neptune no es un sustituto directo de Neo4j. Neptune es un servicio de base de datos de gráficos totalmente gestionado con características empresariales como alta disponibilidad y alta durabilidad que es arquitectónicamente diferente de Neo4j. Neptune se basa en instancias, con una única instancia de escritor principal y hasta 15 instancias de réplica de lectura que permiten escalar la capacidad de lectura horizontalmente. Con [Neptune sin servidor](neptune-serverless.md), puede escalar y reducir verticalmente y de forma automática su capacidad informática en función del volumen de consultas. Esto es independiente del almacenamiento de Neptune, que se escala automáticamente a medida que se van añadiendo datos.

Neptune es compatible con la [especificación estándar de openCypher de código abierto, versión 9](https://s3.amazonaws.com/artifacts.opencypher.org/openCypher9.pdf). En AWS, creemos que el código abierto es bueno para todos y estamos comprometidos tanto a llevar el valor del código abierto a nuestros clientes como a llevar la excelencia operativa AWS a las comunidades de código abierto.

Sin embargo, muchas aplicaciones que se ejecutan en Neo4j también utilizan características propias que no son de código abierto y que Neptune no admite. Por ejemplo, Neptune no admite los procedimientos de APOC, algunas cláusulas y funciones específicas de Cypher ni tipos de datos `Char`, `Date` o `Duration`. Neptune convierte automáticamente los tipos de datos que faltan en [tipos de datos compatibles](bulk-load-tutorial-format-opencypher.md#bulk-load-tutorial-format-opencypher-data-types).

Además de OpenCypher, Neptune también es compatible con el lenguaje de consulta [Apache TinkerPop Gremlin](https://tinkerpop.apache.org/docs/current/reference/#traversal) para gráficos de propiedades (así como con SPARQL para datos RDF). Gremlin puede interoperar con openCypher en el mismo gráfico de propiedades y, en muchos casos, se puede usar Gremlin para proporcionar funciones que openCypher no proporciona. A continuación se muestra una comparación rápida de los dos lenguajes:


|  | openCypher | Gremlin | 
| --- | --- | --- | 
| Style (Estilo) | Declarativo | Imperativo | 
| Sintaxis |  Coincidencia de patrones <pre>Match p=(a)-[:route]->(d)<br />WHERE a.code='ANC'<br />RETURN p<br /></pre>  |  Basado en la transversalidad <pre>g.V().has('code', 'ANC').<br />out('route').path().<br />by(elementMap())</pre>  | 
| Facilidad de uso | Inspirado en SQL, legible por personas que no son programadores | Curva de aprendizaje más pronunciada, similar a la de lenguajes de programación como Java | 
| Flexibilidad | Bajo | Alto | 
| Soporte de consultas | Consultas basadas en cadenas | Consultas basadas en cadenas o código en línea compatibles con las bibliotecas cliente | 
| Clientes | HTTPS y Bolt | HTTPS y Websockets | 

Por lo general, no es necesario cambiar el modelo de datos para migrar de Neo4j a Neptune, ya que tanto Neo4j como Neptune admiten datos de gráficos de propiedades etiquetadas (LPG). Sin embargo, Neptune presenta algunas diferencias en la arquitectura y el modelo de datos que puede sacar partido para optimizar el rendimiento. Por ejemplo:
+ A Neptune IDs se les trata como ciudadanos de primera clase.
+ Neptune utiliza [políticas de AWS Identity and Access Management (IAM)](iam-auth.md) para proteger el acceso a los datos de sus gráficos de forma flexible y detallada.
+ Neptune ofrece varias formas de [utilizar los cuadernos de Jupyter](graph-notebooks.md) para ejecutar consultas y [visualizar los resultados](notebooks-visualization.md). Neptune también funciona con [herramientas de visualización de terceros](visualization-tools.md).
+ >Aunque Neptune no tiene un sustituto directo para la biblioteca Graph Data Science (GDS) de Neo4j, Neptune admite el análisis de gráficos en la actualidad a través de una variedad de soluciones. Por ejemplo, varios [cuadernos de muestra](https://github.com/aws/graph-notebook/tree/main/src/graph_notebook/notebooks/01-Neptune-Database/03-Sample-Applications/06-Data-Science-Samples) muestran cómo aprovechar la [integración de Neptune con AWS el SDK de Pandas](https://github.com/amazon-archives/fully-automated-neo4j-to-neptune) en entornos de Python para ejecutar análisis en datos de gráficos.

Si tienes alguna duda, ponte en contacto con el servicio de AWS asistencia o con el equipo de tu AWS cuenta. Usamos sus comentarios para priorizar las nuevas características que se adapten a sus necesidades.

# Preparación para migrar de Neo4j a Neptune
<a name="preparing-to-migrate-from-neo4j"></a>

 La migración de la base de datos de gráficos de Neo4j al servicio de base de datos de gráficos de Neptune se puede abordar principalmente de dos maneras: redefiniendo la plataforma o refactorizando/rediseñando la arquitectura. El enfoque de redefinición implica modificar el modelo de datos y la arquitectura de la aplicación existentes para aprovechar al máximo las capacidades de Neptune, mientras que el enfoque de refactorización se centra en encontrar componentes equivalentes en Neptune para crear una implementación comparable. En la práctica, a menudo se utiliza una combinación de estas estrategias, ya que el proceso de migración implica equilibrar la arquitectura de Neptune de destino con las restricciones y requisitos de la implementación de Neo4j existente. Independientemente del enfoque, la clave es trabajar de forma retrospectiva a partir de los casos de uso de la aplicación para diseñar el modelo de datos, las consultas y la arquitectura general que mejor se adapten a sus necesidades. 

## Métodos relacionados con la migración
<a name="migration-approaches"></a>

Al migrar una aplicación de Neo4j a Neptune, recomendamos una de estas dos estrategias: redefinir la plataforma o refactorizar/rediseñar la arquitectura. Para obtener más información sobre las estrategias de migración, consulte [Seis estrategias para migrar aplicaciones a la nube](https://aws.amazon.com/blogs/enterprise-strategy/6-strategies-for-migrating-applications-to-the-cloud/), una publicación del blog de Stephen Orban.

El *enfoque de cambio de plataforma*, a veces denominado *lift-tinker-and-shift*, implica los siguientes pasos:
+ Identificar los casos de uso para los que la aplicación está diseñada.
+ Modificar el modelo de datos de gráficos y la arquitectura de la aplicación existentes para abordar mejor estas necesidades de carga de trabajo con las capacidades de Neptune.
+ Determinar cómo migrar los datos, las consultas y otras partes de la aplicación de origen al modelo y la arquitectura de destino.

Este método de empezar por el final le permite migrar su aplicación al tipo de solución de Neptune que podría diseñar si se tratara de un proyecto completamente nuevo.

El *método de refactorización,* por el contrario, implica:
+ Identificar los componentes de la implementación existente, incluidos la infraestructura, los datos, las consultas y las capacidades de las aplicaciones.
+ Encontrar equivalentes en Neptune que puedan usarse para crear una implementación comparable.

Este método de empezar por el principio busca cambiar una implementación por otra.

En la práctica, es probable que adopte una combinación de estos dos métodos. Puede comenzar con un caso de uso, diseñar la arquitectura de Neptune de destino, pero luego pasar a la implementación existente de Neo4j para identificar las restricciones e invariables que tendrá que mantener. Por ejemplo, puede que tenga que seguir integrándose con otros sistemas externos o seguir ofreciendo aplicaciones gráficas específicas APIs para los usuarios. Con esta información, puede determinar qué datos ya existen para pasarlos al modelo de destino y cuáles deben proceder de otro lugar.

En otros casos, podría empezar por analizar una parte específica de la implementación de Neo4j como el mejor origen de información sobre el trabajo al que está destinada la aplicación. Ese tipo de arqueología en la aplicación existente puede ayudar a definir un caso de uso que luego se pueda diseñar con el fin de sacar partido de las capacidades de Neptune.

Ya sea que esté creando una nueva aplicación con Neptune o migrando una aplicación existente desde Neo4j, le recomendamos empezar por el final a partir de los casos de uso para diseñar un modelo de datos, un conjunto de consultas y una arquitectura de aplicaciones que aborde las necesidades de su empresa.

# Diferencias arquitectónicas entre Neptune y Neo4j
<a name="migration-architectural-differences"></a>

Cuando los clientes se plantean por primera vez migrar una aplicación de Neo4j a Neptune, a menudo resulta tentador realizar una like-to-like comparación basada en el tamaño de la instancia. Sin embargo, las arquitecturas de Neo4j y Neptune tienen diferencias fundamentales. Neo4j se basa en un all-in-one enfoque en el que la carga de datos, la ETL de datos, las consultas a las aplicaciones, el almacenamiento de datos y las operaciones de administración se realizan en el mismo conjunto de recursos informáticos, como las instancias EC2.

Neptune, por el contrario, es una base de datos de gráficos centrada en OLTP en la que la arquitectura separa las responsabilidades y en la que los recursos se desacoplan para que puedan escalarse de forma dinámica e independiente.

Al migrar de Neo4j a Neptune, determine los requisitos de durabilidad, disponibilidad y escalabilidad de los datos de la aplicación. La arquitectura de clústeres de Neptune simplifica el diseño de aplicaciones que requieren una alta durabilidad, disponibilidad y escalabilidad. Una vez que comprenda la arquitectura de clústeres de Neptune, podrá diseñar una topología de clústeres de Neptune que haga frente a estos requisitos.

## La arquitectura de clústeres de Neo4j
<a name="migration-neo4j-cluster-architecture"></a>

Muchas aplicaciones de producción utilizan la [agrupación en clústeres causal](https://neo4j.com/docs/operations-manual/current/clustering/introduction/) de Neo4j para proporcionar durabilidad, alta disponibilidad y escalabilidad de los datos. La arquitectura de agrupación en clústeres de Neo4j utiliza instancias de servidor de núcleo e instancias de réplica de lectura:
+ Los servidores de núcleo garantizan la durabilidad de los datos y la tolerancia a los errores al replicar los datos mediante el protocolo Raft.
+ Las réplicas de lectura utilizan el envío de registros de transacciones para replicar datos de forma asíncrona para cargas de trabajo de alto rendimiento de lectura.

Cada instancia de un clúster, ya sea un servidor de núcleo o una réplica de lectura, incluye una copia completa de los datos del gráfico.

## Arquitectura de clústeres de Neptune
<a name="migration-neptune-cluster-architecture"></a>

[Un clúster de Neptune](feature-overview-db-clusters.md) consta de una instancia de escritor principal y hasta 15 instancias de réplica de lectura. Todas las instancias del clúster comparten el mismo servicio de almacenamiento distribuido subyacente que es independiente de las instancias.
+ La instancia de escritor principal coordina todas las operaciones de escritura en la base de datos y se puede escalar verticalmente para ofrecer un soporte flexible a diferentes cargas de trabajo de escritura. También admite operaciones de lectura.
+ Las instancias de réplica de lectura admiten operaciones de lectura del volumen de almacenamiento subyacente y permiten escalar horizontalmente para admitir cargas de trabajo de lectura elevadas. También proporcionan alta disponibilidad al servir como destinos de conmutación por error para la instancia principal.
**nota**  
En el caso de cargas de trabajo de escritura intensas, se recomienda escalar las instancias de réplica de lectura para que tengan el mismo tamaño que la instancia de escritor, con el fin de garantizar que los lectores puedan mantener la coherencia con los cambios realizados en los datos.
+ El volumen de almacenamiento subyacente escala la capacidad de almacenamiento automáticamente a medida que aumentan los datos de la base de datos, hasta 128 tebibytes (TiB) de almacenamiento.

Los tamaños de las instancias son dinámicos e independientes. Se puede cambiar el tamaño de cada instancia mientras el clúster esté en ejecución, y las réplicas de lectura se pueden añadir o eliminar mientras el clúster esté en ejecución.

La característica [Neptune sin servidor](neptune-serverless.md) puede escalar y reducir verticalmente de forma automática su capacidad de cómputo a medida que la demanda aumenta y disminuye. Esto no solo reduce la sobrecarga administrativa, sino que también permite configurar la base de datos para gestionar los grandes picos de demanda sin que disminuya el rendimiento ni sea necesario un aprovisionamiento excesivo.

Puede detener un clúster de Neptune durante un máximo de siete días.

Neptune también admite el [escalado automático](manage-console-autoscaling.md) para ajustar automáticamente los tamaños de las instancias de lector en función de la carga de trabajo.

Con la [característica de base de datos global](neptune-global-database.md) de Neptune, puede duplicar un clúster en otras cinco regiones como máximo.

Neptune también ofrece [tolerancia a errores por diseño](backup-restore-overview-fault-tolerance.md):
+ El volumen del clúster que proporciona almacenamiento de datos a todas las instancias del clúster abarca varias zonas de disponibilidad (AZs) en una sola. Región de AWS Cada zona de disponibilidad incluye una copia completa de los datos del clúster.
+ Si la instancia principal deja de estar disponible, Neptune realiza automáticamente la conmutación por error a una réplica de lectura existente sin pérdida de datos, normalmente en menos de 30 segundos. Si no hay réplicas de lectura en el clúster, Neptune aprovisiona automáticamente una nueva instancia principal, una vez más, sin pérdida de datos.

Lo que todo esto significa es que, al migrar de un clúster causal de Neo4j a Neptune, no es necesario diseñar la topología del clúster de forma explícita para lograr alta disponibilidad y durabilidad de los datos. Esto le permite ajustar el tamaño del clúster a las cargas de trabajo de lectura y escritura previstas y a cualquier requisito de mayor disponibilidad que pueda tener de varias maneras:
+ Para escalar las operaciones de lectura, [añada instancias de réplica de lectura](feature-overview-db-clusters.md#feature-overview-read-replicas) o habilite la funcionalidad [Neptune sin servidor](neptune-serverless.md).
+ Para mejorar la disponibilidad, distribuya la instancia principal y lea las réplicas del clúster en varias zonas de disponibilidad ()AZs.
+ Para reducir el tiempo de conmutación por error, aprovisione al menos una instancia de réplica de lectura que pueda servir como destino de conmutación por error para la principal. Puede determinar el orden en que se promueven las instancias de réplicas de lectura a la principal tras un error mediante la [asignación de una prioridad a cada réplica](manage-console-add-replicas.md). Una práctica recomendada es asegurarse que un destino de conmutación por error tenga una clase de instancia capaz de gestionar la carga de trabajo de escritura de la aplicación si se promociona a principal.

# Diferencias de almacenamiento de datos entre Neptune y Neo4j
<a name="migration-storage-differences"></a>

Neptune utiliza un [modelo de datos de gráficos](feature-overview-data-model.md) basado en un modelo cuádruple nativo. Al migrar los datos a Neptune, hay varias diferencias en la arquitectura del modelo de datos y la capa de almacenamiento que debe tener en cuenta para hacer un uso óptimo del almacenamiento compartido distribuido y escalable que proporciona Neptune:
+ Neptune no utiliza ningún esquema ni restricciones definidos de forma explícita. Permite añadir nodos, bordes y propiedades de forma dinámica sin tener que definir el esquema con antelación. Neptune no limita los valores ni los tipos de datos almacenados, salvo en los casos indicados en [Límites de Neptune](limits.md#limits-properties). Como parte de la arquitectura de almacenamiento de Neptune, los datos también se [indexan automáticamente](feature-overview-storage-indexing.md) de forma que se gestionan muchos de los patrones de acceso más comunes. Esta arquitectura de almacenamiento elimina la sobrecarga operativa que supone la creación y administración del esquema de la base de datos y la optimización de índices.
+ Neptune proporciona una arquitectura única de almacenamiento distribuido y compartido que se reduce horizontalmente de forma automática en fragmentos de 10 GB a medida que aumentan las necesidades de almacenamiento de la base de datos, hasta 128 tebibytes (TiB). Esta capa de almacenamiento es fiable, duradera y tolerante a errores, y los datos se copian seis veces, dos veces en cada una de las tres zonas de disponibilidad. Proporciona a todos los clústeres de Neptune una capa de almacenamiento de datos de alta disponibilidad y tolerante a errores de forma predeterminada. La arquitectura de almacenamiento de Neptune reduce los costos y elimina la necesidad de aprovisionar o sobreaprovisionar almacenamiento para gestionar el crecimiento futuro de los datos.

Antes de migrar los datos a Neptune, le recomendamos que se familiarice con el [modelo de datos de gráficos de propiedades](feature-overview-storage-indexing.md#feature-overview-storage-indexing-gremlin) de Neptune y la [semántica de transacciones](transactions.md). 

# Diferencias operativas entre Neptune y Neo4j
<a name="migration-operational-differences"></a>

Neptune es un servicio totalmente gestionado que automatiza muchas de las tareas operativas normales que tendría que realizar al utilizar bases de datos autoadministradas o en las instalaciones, como Neo4j Enterprise o Community Edition:
+ **[Copias de seguridad automatizadas](backup-restore.md#backup-restore-overview-backups)**: Neptune hace copias de seguridad del volumen del clúster automáticamente y las conserva durante el periodo de retención que se especifique (de 1 a 35 días). Estas copias de seguridad son continuas e incrementales para que se pueda restaurar con rapidez en cualquier momento durante el periodo de retención. No se produce ningún impacto en el desempeño ni ninguna interrupción del servicio de base de datos durante la escritura de los datos de copia de seguridad.
+ **[Instantáneas manuales](backup-restore.md)**: Neptune le permite crear una instantánea del volumen de almacenamiento del clúster de base de datos para crear una copia de seguridad de todo el clúster de base de datos. Este tipo de instantánea se puede usar luego para restaurar la base de datos, hacer una copia de la misma y compartirla entre cuentas.
+ **[Clonación](manage-console-cloning.md)**: Neptune admite una característica de clonación que le permite crear rápidamente clones rentables de una base de datos. Los clones utilizan un copy-on-write protocolo que requiere un espacio adicional mínimo una vez creados. La clonación de bases de datos es una forma eficaz de probar nuevas características o actualizaciones de Neptune sin interrumpir el clúster de origen.
+ **[Monitorización](monitoring.md)**: Neptune proporciona varios métodos para monitorizar el rendimiento y el uso del clúster, entre los que se incluyen:
  + Estado de la instancia
  + Integración con Amazon CloudWatch y AWS CloudTrail
  + Capacidades de registro de auditoría
  + Notificaciones de eventos
  + Etiquetado
+ **[Seguridad](security.md)**: Neptune proporciona un entorno seguro de forma predeterminada. Un clúster reside dentro de una VPC privada que aísla la red de otros recursos. Todo el tráfico se cifra mediante SSL, y todos los datos se cifran en reposo utilizando AWS KMS.

  [Además, Neptune se integra con AWS Identity and Access Management (IAM) para proporcionar autenticación.](iam-auth.md) Al especificar [las claves de condición de IAM](iam-condition-keys.md), puede utilizar las políticas de IAM para proporcionar un control de acceso detallado sobre las [acciones de datos](iam-data-access-policies.md).

## Diferencias de herramientas e integración entre Neptune y Neo4j
<a name="migration-tooling-differences"></a>

Neptune tiene una arquitectura de integraciones y herramientas diferente a la de Neo4j, lo que puede afectar a la arquitectura de la aplicación. Neptune utiliza los recursos informáticos del clúster para procesar las consultas, pero aprovecha otros best-in-class AWS servicios para funciones como la búsqueda de texto completo (mediante OpenSearch), ETL (mediante Glue), etc. Para obtener una lista completa de estas integraciones, consulte [Integraciones de Neptune](integrations.md).

# Aprovisionamiento de la infraestructura al migrar de Neo4j a Neptune
<a name="migration-provisioning-infrastructure"></a>

Los clústeres de Amazon Neptune se han diseñado para reducirse horizontalmente en tres dimensiones: almacenamiento, capacidad de escritura y capacidad de lectura. En las siguientes secciones se analizan las opciones específicas que se deben tener en cuenta al llevar a cabo la migración.

## Aprovisionamiento del almacenamiento
<a name="migration-provisioning-storage"></a>

El almacenamiento de cualquier clúster de Neptune se aprovisiona automáticamente, sin ningún tipo de sobrecarga administrativa por su parte. Cambia el tamaño de forma dinámica en fragmentos de 10 GB a medida que aumentan las necesidades de almacenamiento del clúster. Como resultado, no hay necesidad de estimar, aprovisionar ni sobreaprovisionar el almacenamiento para gestionar el futuro crecimiento de los datos.

## Aprovisionamiento de la capacidad de escritura
<a name="migration-provisioning-write-capacity"></a>

Neptune proporciona una instancia única de escritor que se puede escalar verticalmente a cualquier tamaño de instancia disponible en la [página de precios de Neptune](https://aws.amazon.com/neptune/pricing/). Al leer y escribir los datos en una instancia de escritor, todas las transacciones cumplen con las normas ACID, con el aislamiento de datos, tal y como se define en [Niveles de aislamiento de transacciones en Neptune](transactions-neptune.md).

Para elegir un tamaño óptimo para una instancia de escritor, es necesario ejecutar pruebas de carga para determinar el tamaño de instancia óptimo para la carga de trabajo. Para cambiar el tamaño de cualquier instancia de Neptune en cualquier momento, [modifique la clase de instancia de base de datos](manage-console-instances-modify.md). Puede estimar el tamaño de una instancia inicial en función de la simultaneidad y la latencia media de las consultas, tal y como se describe a continuación en [Estimación del tamaño óptimo de la instancia al aprovisionar el clúster](#migration-provisioning-instance-sizing).

## Aprovisionamiento de la capacidad de lectura
<a name="migration-provisioning-read-capacity"></a>

Neptune se ha diseñado para escalar las instancias de lectura de réplica tanto horizontalmente, añadiendo hasta 15 de ellas dentro de un clúster (o más en una [base de datos global de Neptune](neptune-global-database.md)), como verticalmente a cualquier tamaño de instancia disponible en la[página de precios de Neptune](https://aws.amazon.com/neptune/pricing/). Todas las instancias de réplica de lectura de Neptune utilizan el mismo volumen de almacenamiento subyacente, lo que permite la replicación transparente de los datos con un retraso mínimo.

Además de permitir el escalado horizontal de las solicitudes de lectura dentro de un clúster de Neptune, las réplicas de lectura también actúan como objetivos de conmutación por error para la instancia de escritor con el fin de que haya alta disponibilidad. Consulte [Directrices operativas básicas de Amazon Neptune](best-practices-general-basic.md) para obtener sugerencias sobre cómo determinar el número y la ubicación adecuados de las réplicas de lectura en el clúster.

Para las aplicaciones en las que la conectividad y la carga de trabajo son impredecibles, Neptune también admite una [característica de escalado automático](manage-console-autoscaling.md) que puede ajustar automáticamente el número de réplicas de Neptune en función de los criterios que especifique.

Para determinar el tamaño y la cantidad óptimos de instancias de réplica de lectura, es necesario ejecutar pruebas de carga para determinar las características de la carga de trabajo de lectura que deben admitir. Para cambiar el tamaño de cualquier instancia de Neptune en cualquier momento, [modifique la clase de instancia de base de datos](manage-console-instances-modify.md). Puede estimar el tamaño de una instancia inicial en función de la simultaneidad y la latencia media de las consultas, tal y como se describe en la [siguiente sección](#migration-provisioning-instance-sizing).

## Uso de Neptune sin servidor para escalar las instancias de lector y escritor automáticamente según sea necesario
<a name="migration-provisioning-serverless"></a>

Si bien a menudo resulta útil poder estimar la capacidad de cómputo que requerirán las cargas de trabajo previstas, puede configurar la característica [Neptune sin servidor](neptune-serverless.md) para escalar y reducir verticalmente de forma automática la capacidad de lectura y escritura. Esto puede ayudarle a hacer frente a los requisitos de máxima demanda y, al mismo tiempo, reducirla automáticamente cuando la demanda disminuya.

## Estimación del tamaño óptimo de la instancia al aprovisionar el clúster
<a name="migration-provisioning-instance-sizing"></a>

La estimación del tamaño óptimo de la instancia requiere conocer la latencia media de consultas en Neptune, cuando se ejecuta la carga de trabajo, así como el número de consultas simultáneas que se estén procesando. Para calcular una estimación aproximada del tamaño de la instancia, multiplique la latencia media de las consultas por el número de consultas simultáneas. Esto le proporciona el número medio de subprocesos simultáneos necesarios para gestionar la carga de trabajo.

[Cada vCPU de una instancia de Neptune puede admitir dos subprocesos de consulta simultáneos, por lo que dividir los subprocesos entre 2 proporciona el número de v CPUs necesario, que luego se puede correlacionar con el tamaño de instancia adecuado en la página de precios de Neptune.](https://aws.amazon.com/neptune/pricing/) Por ejemplo:

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

Al correlacionar esto con el número de v CPUs en una instancia, obtenemos una estimación aproximada de que a `r5.4xlarge` sería la instancia recomendada para esta carga de trabajo. Esta estimación es aproximada y solo pretende proporcionar una orientación inicial sobre la selección del tamaño de la instancia. Cualquier solicitud debe someterse a un ejercicio de ajuste de tamaño adecuado para determinar el número y los tipos de instancias adecuados para la carga de trabajo.

También se deben tener en cuenta los requisitos de memoria, así como los requisitos de procesamiento. Neptune es más eficaz cuando los datos a los que acceden las consultas están disponibles en la caché del grupo de búferes de la memoria principal. El aprovisionamiento de suficiente memoria también puede reducir I/O los costes de forma significativa.

Puede encontrar información e instrucciones adicionales sobre el tamaño de las instancias en un clúster de Neptune en la página [Dimensionamiento de las instancias de base de datos en un clúster de base de datos de Neptune](feature-overview-db-clusters.md#feature-overview-sizing-instances).

# Migración de datos de Neo4j a Neptune
<a name="migration-data-migration"></a>

Al realizar una migración de Neo4j a Amazon Neptune, la migración de los datos es un paso importante del proceso. Existen varios métodos para migrar datos. El método correcto viene determinado por las necesidades de la aplicación, el tamaño de los datos y el tipo de migración deseado. Sin embargo, muchas de estas migraciones requieren una evaluación de las mismas consideraciones, algunas de las cuales se destacan a continuación.

**nota**  
Consulte [Migración de una base de datos de gráficos de Neo4j a Neptune con una utilidad totalmente automatizada](https://aws.amazon.com/blogs/database/migrating-a-neo4j-graph-database-to-amazon-neptune-with-a-fully-automated-utility/) en el [blog de bases de datos de AWS](https://aws.amazon.com/blogs/?awsf.blog-master-category=category%23database) para obtener una explicación completa paso a paso de un ejemplo de cómo realizar una migración de datos sin conexión.

## Evaluación de la migración de datos de Neo4j a Neptune
<a name="migration-data-assessment"></a>

El primer paso a la hora de evaluar cualquier migración de datos es determinar cómo se van a migrar los datos. Las opciones dependen de la arquitectura de la aplicación que se va a migrar, del tamaño de los datos y de las necesidades de disponibilidad durante la migración. Por lo general, las migraciones suelen clasificarse en una de las siguientes dos categorías: en línea o sin conexión.

Las migraciones sin conexión suelen ser las más sencillas de realizar, ya que la aplicación no acepta tráfico de lectura o escritura durante la migración. Cuando la aplicación deja de aceptar tráfico, los datos se pueden exportar, optimizar e importar, y la aplicación se puede probar antes de volver a habilitarla.

Las migraciones en línea son más complejas, ya que la aplicación aún necesita aceptar el tráfico de lectura y escritura mientras se migran los datos. Las necesidades exactas de cada migración en línea pueden diferir, pero la arquitectura general suele ser similar a la siguiente:
+ Es necesario habilitar en Neo4j la información sobre los cambios continuos realizados en la base de datos. Para ello, configure [Neo4j Streams como fuente de un clúster](https://neo4j.com/labs/kafka/4.0/producer/) de Kafka.
+ Una vez hecho esto, se puede realizar una exportación del sistema en ejecución siguiendo las instrucciones de [Exportación de datos de Neo4j al migrar a Neptune](#migration-data-exporting) y el tiempo indicado para luego correlacionarlo con el tema de Kafka.
+ A continuación, los datos exportados se importan a Neptune, siguiendo las instrucciones de [Importación de datos de Neo4j al migrar a Neptune](#migration-data-importing).
+ Después, los datos modificados de la transmisión de Kafka se pueden copiar al clúster de Neptune mediante una arquitectura similar a la descrita en [Escribir en Amazon Neptune desde Amazon Kinesis Data Streams](https://github.com/aws-samples/amazon-neptune-samples/tree/master/gremlin/stream-2-neptune). Tenga en cuenta que la replicación de los cambios se puede ejecutar en paralelo para validar la nueva arquitectura y el rendimiento de la aplicación.
+ Una vez validada la migración de datos, el tráfico de la aplicación se puede redirigir al clúster de Neptune y se puede retirar la instancia de Neo4j.

## Optimizaciones de modelos de datos para migrar de Neo4j a Neptune
<a name="migration-data-model-optimization"></a>

Tanto Neptune como Neo4j admiten gráficos de propiedades etiquetadas (LPG). Sin embargo, Neptune presenta algunas diferencias en la arquitectura y el modelo de datos que puede sacar partido para optimizar el rendimiento:

### Optimización de los identificadores de nodos y bordes
<a name="migration-data-node-edge-id-optimization"></a>

Neo4j genera automáticamente identificadores numéricos largos. Con Cypher, puede hacer referencia a los nodos según su ID, pero, en general, se recomienda buscar los nodos mediante una propiedad indexada.

Neptune le permite [proporcionar sus propios identificadores basados en cadenas para vértices y bordes](access-graph-gremlin-differences.md#feature-gremlin-differences-user-supplied-ids). Si no proporciona sus propios identificadores, Neptune genera automáticamente representaciones en cadena de los UUID para los nuevos vértices y bordes.

Si migra datos de Neo4j a Neptune exportándolos desde Neo4j y luego importándolos de forma masiva a Neptune, puede conservar los ID de Neo4j. Los valores numéricos generados por Neo4j pueden actuar como identificadores proporcionados por el usuario al importarlos a Neptune, donde se representan como cadenas en lugar de valores numéricos.

Sin embargo, hay circunstancias en las que es posible que desee promover una propiedad de vértice para que se convierta en un ID de vértice. Así como buscar un nodo con una propiedad indexada es la forma más rápida de encontrar un nodo en Neo4j, buscar un vértice según el ID es la forma más rápida de encontrar un vértice en Neptune. Por lo tanto, si puede identificar una propiedad de vértice adecuada que incluya valores únicos, debe plantearse reemplazar el valor \$1id del vértice por el valor de propiedad designado en los archivos CSV de carga masiva. Si lo hace, también tendrá que volver a escribir los valores de las bordes \$1from y \$1to correspondientes en los archivos CSV.

### Restricciones del esquema al migrar datos de Neo4j a Neptune
<a name="migration-data-schema-constraints"></a>

En Neptune, la única restricción de esquema disponible es la exclusividad del ID de un nodo o un borde. Se recomienda a las aplicaciones que necesiten sacar partido de una restricción de exclusividad que utilicen este método para lograr una restricción de exclusividad especificando el identificador del nodo o del borde. Si la aplicación utilizó varias columnas como restricción de exclusividad, el ID puede configurarse en una combinación de estos valores. Por ejemplo, `id=123, code='SEA'` podría representarse como `ID='123_SEA'` para lograr una restricción de exclusividad compleja.

### Optimización de la dirección de los bordes al migrar datos de Neo4j a Neptune
<a name="migration-data-edge-direction"></a>

Cuando se añaden nodos, bordes o propiedades a Neptune, se [indexan automáticamente de tres formas diferentes](feature-overview-storage-indexing.md), con un [cuarto índice opcional](features-lab-mode.md#features-lab-mode-features-osgp-index). Debido a la forma en que Neptune crea y [usa los índices](feature-overview-storage-indexing.md), las consultas que siguen los bordes salientes son más eficaces que las que usan los bordes entrantes. En cuanto al [modelo de almacenamiento de datos de gráficos](feature-overview-data-model.md) de Neptune, se trata de búsquedas basadas en temas que utilizan el índice SPOG.

Si, al migrar el modelo de datos y las consultas a Neptune, descubre que las consultas más importantes se basan en atravesar los bordes entrantes donde hay un alto grado de distribución, puede plantearse modificar el modelo para que estos recorridos sigan los bordes salientes, especialmente si no puede especificar las etiquetas de borde que desea atravesar. Para ello, invierta la dirección de los bordes relevantes y actualice las etiquetas de los bordes para que reflejen la semántica de este cambio de dirección. Por ejemplo, podría cambiar:

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

Para realizar este cambio en un [archivo CSV de borde de carga masiva](bulk-load-tutorial-format.md), basta con cambiar los encabezados de las columnas `~from` y `~to` y actualizar los valores de la columna `~label`.

Como alternativa a la reversión de la dirección de los bordes, puede habilitar un [cuarto índice de Neptune, el índice OSGP](feature-overview-storage-indexing.md#feature-overview-storage-indexing-osgp), que hace que el proceso de atravesar los bordes entrantes o las búsquedas basadas en objetos sean mucho más eficaces. Sin embargo, si se habilita este cuarto índice, se reducirán las tasas de inserción y se necesitará más espacio de almacenamiento.

### Optimización del filtrado al migrar datos de Neo4j a Neptune
<a name="migration-data-filtering"></a>

Neptune está optimizado para funcionar mejor cuando las propiedades se filtran a la propiedad más selectiva disponible. Cuando se utilizan varios filtros, se busca el conjunto de elementos que coincidan entre ellos y, a continuación, se calcula la superposición de todos estos conjuntos. Cuando es posible, la combinación de varias propiedades en una única propiedad minimiza el número de búsquedas en el índice y reduce la latencia de una consulta.

Por ejemplo, esta consulta utiliza dos búsquedas de índices y una combinación:

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

Esta consulta recupera la misma información mediante una única búsqueda de índice:

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

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

Neptune admite [tipos de datos diferentes](bulk-load-tutorial-format-opencypher.md#bulk-load-tutorial-format-opencypher-data-types) a los de Neo4j.

**Mapeos de tipos de datos de Neo4j a tipos de datos compatibles con Neptune**
+ **Lógica**: `Boolean`

  Asigne este valor en Neptune a `Bool` o `Boolean`.
+ **Numérica**: `Number`

  Asigne este valor en Neptune al más estrecho de los siguientes tipos de openCypher de Neptune que puedan admitir todos los valores de la propiedad numérica en cuestión:

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

  Asigne este valor en Neptune a `String`.
+ **Momento específico**:

  ```
    Date
    Time
    LocalTime
    DateTime
    LocalDateTime
  ```

  Asigne estos valores en Neptune a `Date` como UTC mediante uno de los siguientes formatos ISO-8601 compatibles con Neptune:

  ```
    yyyy-MM-dd
    yyyy-MM-ddTHH:mm
    yyyy-MM-ddTHH:mm:ss
    yyyy-MM-ddTHH:mm:ssZ
  ```
+ **Duración**: `Duration`

  Asigne este valor en Neptune a un valor numérico para la aritmética de fechas, si es necesario.
+ **Espacial**: `Point`

  Asigne este valor en Neptune a los valores numéricos de los componentes, cada uno de los cuales se convierte en una propiedad independiente, o expréselo como un valor de cadena para que lo interprete la aplicación cliente. Tenga en cuenta que la integración de [búsqueda de texto completo](full-text-search.md) de Neptune mediante OpenSearch le permite indexar las propiedades de geolocalización.

### Migración de propiedades multivalor de Neo4j a Neptune
<a name="migration-data-cardinality"></a>

Neo4j permite almacenar [listas homogéneas de tipos sencillas](https://neo4j.com/docs/cypher-manual/current/values-and-types/) como propiedades tanto de los nodos como de los bordes. Estas listas pueden incluir valores duplicados.

Sin embargo, Neptune solo permite una [cardinalidad en conjuntos o única](access-graph-gremlin-differences.md#feature-gremlin-differences-vertex-property-cardinality) para las propiedades de los vértices y una cardinalidad única para las propiedades de los bordes en los datos de gráficos de propiedades. Como resultado, no existe una migración directa de las propiedades de la lista de nodos de Neo4j que incluyan valores duplicados en las propiedades de los vértices de Neptune, ni de las propiedades de la lista de relaciones de Neo4j en las propiedades de los bordes de Neptune.

Algunas posibles estrategias para migrar propiedades de nodos multivalor de Neo4j con valores duplicados a Neptune son las siguientes:
+ Descarte los valores duplicados y convierta la propiedad del nodo multivalor de Neo4j en una propiedad de vértice de Neptune de cardinalidad en conjuntos. Tenga en cuenta que es posible que el conjunto de Neptune no refleje el orden de los elementos de la propiedad multivalor original de Neo4j.
+ Convierta la propiedad de nodo multivalor de Neo4j en una representación de cadena de una lista con formato JSON en una propiedad de cadena de vértices de Neptune.
+ Extraiga cada uno de los valores de propiedad multivalor en un vértice independiente con una propiedad de valor y conecte esos vértices al vértice principal mediante un borde etiquetado con el nombre de la propiedad.

Asimismo, algunas posibles estrategias para migrar propiedades de relaciones multivalor de Neo4j en Neptune son las siguientes:
+ Convierta la propiedad de relación multivalor de Neo4j en una representación de cadena de una lista con formato JSON en una propiedad de cadena de bordes de Neptune.
+ Refactorice la relación Neo4j en los bordes entrantes y salientes de Neptune asociados a un vértice intermedio. Extraiga cada uno de los valores de propiedad de relación multivalor en un vértice independiente con una propiedad de valor y conecte esos vértices al vértice intermedio mediante un borde etiquetado con el nombre de la propiedad.

Tenga en cuenta que la representación en cadena de una lista con formato JSON es opaca para el lenguaje de consultas de openCypher, aunque openCypher incluye un predicado `CONTAINS` que permite realizar búsquedas sencillas dentro de los valores de cadena.

## Exportación de datos de Neo4j al migrar a Neptune
<a name="migration-data-exporting"></a>

Al exportar datos de Neo4j, utilice los procedimientos de APOC para exportar a [CSV](https://neo4j.com/labs/apoc/4.1/export/csv/) o a [GraphML](https://neo4j.com/labs/apoc/4.1/export/graphml/). Aunque es posible exportar a otros formatos, existen [herramientas de código abierto](https://github.com/awslabs/amazon-neptune-tools/tree/master/neo4j-to-neptune) para convertir los datos CSV exportados desde Neo4j al formato de carga masiva Neptune, y también [herramientas de código abierto](https://github.com/awslabs/amazon-neptune-tools/tree/master/graphml2csv) para convertir los datos de GraphML exportados de Neo4j al formato de carga masiva de Neptune.

También puede exportar los datos directamente a Amazon S3 mediante los distintos procedimientos de APOC. La exportación a un bucket de Amazon S3 está deshabilitada de forma predeterminada, pero se puede habilitar mediante los procedimientos destacados en [Exportación a Amazon S3](https://neo4j.com/labs/apoc/4.3/export/csv/#export-csv-s3-export) en la documentación sobre APOC de Neo4j.

## Importación de datos de Neo4j al migrar a Neptune
<a name="migration-data-importing"></a>

Puede importar datos a Neptune mediante el [programa de carga masiva de Neptune](bulk-load.md) o mediante la lógica de la aplicación en un lenguaje de consulta compatible, como, por ejemplo, [openCypher](access-graph-opencypher.md).

El programa de carga masiva de Neptune es el método preferido para importar grandes cantidades de datos, ya que proporciona un rendimiento de importación optimizado si se siguen las [prácticas recomendadas](bulk-load-optimize.md). El programa de carga masiva admite [dos formatos CSV diferentes](bulk-load-tutorial-format.md), a los que los datos exportados desde Neo4j se pueden convertir con las utilidades de código abierto mencionadas anteriormente en la sección [Exportación de datos](#migration-data-exporting).

También puede usar openCypher para importar datos con una lógica personalizada con el fin de analizarlos, transformarlos e importarlos. Puede enviar las consultas de openCypher a través del [punto de conexión de HTTPS](access-graph-opencypher-queries.md) (lo que se recomienda) o mediante el [controlador de Bolt](access-graph-opencypher-bolt.md).

# Migración de aplicaciones de Neo4j a Neptune
<a name="migration-app-migration"></a>

Una vez que haya migrado los datos de Neo4j a Neptune, el siguiente paso es migrar la propia aplicación. Al igual que con los datos, existen varios métodos para migrar la aplicación en función de las herramientas que utilice, los requisitos, las diferencias arquitectónicas, etc. A continuación, se describen los aspectos que normalmente es necesario tener en cuenta en este proceso.

## Migración de conexiones al migrar de Neo4j a Neptune
<a name="migration-app-connections"></a>

Si actualmente no utiliza los controladores Bolt, o si desea utilizar una alternativa, puede conectarse al [punto de conexión de HTTPS](access-graph-opencypher-queries.md), que proporciona acceso total a los datos devueltos. 

Si tiene una aplicación que usa el [protocolo Bolt](access-graph-opencypher-bolt.md), puede migrar estas conexiones a Neptune y permitir que las aplicaciones se conecten con los mismos controladores que utilizó en Neo4j. Para conectarse a Neptune, es posible que deba realizar uno o varios de estos cambios en la aplicación:
+ Será necesario actualizar la URL y el puerto para usar los puntos de conexión y el puerto del clúster (el valor predeterminado es 8182).
+ Neptune requiere que todas las conexiones usen SSL, por lo que debe especificar que cada conexión esté cifrada.
+ Neptune administra la autenticación mediante la asignación de [roles y políticas de IAM](iam-auth.md). Los roles y políticas de IAM proporcionan un nivel extremadamente flexible de administración de usuarios dentro de la aplicación, por lo que es importante leer y comprender la [Información general de IAM](iam-auth.md) antes de configurar el clúster.
+ Las conexiones de Bolt se comportan de manera diferente en Neptune que en Neo4j de varias maneras, tal y como se explica en [Comportamiento de conexión de Bolt en Neptune](access-graph-opencypher-bolt.md#access-graph-opencypher-bolt-connections).
+ Puede encontrar más información y sugerencias en [Prácticas recomendadas de Neptune con openCypher y Bolt](best-practices-opencypher.md).

Hay ejemplos de código de lenguajes de uso común, como Java, Python, .NET y NodeJS, y para escenarios de conexión, como, por ejemplo, el uso de la autenticación de IAM, en [Uso del protocolo Bolt para realizar consultas de openCypher a Neptune](access-graph-opencypher-bolt.md).

## Enrutamiento de consultas a instancias de clúster al pasar de Neo4j a Neptune
<a name="migration-app-routing"></a>

Las aplicaciones cliente de Neo4j utilizan un [controlador de enrutamiento](https://neo4j.com/docs/driver-manual/1.7/client-applications/#routing_drivers_bolt_routing) y especifican un [modo de acceso](https://neo4j.com/docs/driver-manual/1.7/sessions-transactions/#driver-transactions-access-mode) para enrutar las solicitudes de lectura y escritura a un servidor adecuado en un clúster causal.

Al migrar una aplicación cliente a Neptune, utilice los [puntos de conexión de Neptune](feature-overview-endpoints.md) para enrutar las consultas de forma eficaz a una instancia adecuada del clúster:
+ Todas las conexiones a Neptune deben utilizar `bolt://` en lugar de `bolt+routing://` o `neo4j://` en la URL.
+ El punto de conexión del clúster se conecta a la instancia principal actual del clúster. Utilice el punto de conexión del clúster para dirigir las solicitudes de escritura al principal.
+ El punto de conexión del lector [distribuye las conexiones](best-practices-general-basic.md#best-practices-general-loadbalance) entre instancias de lectura de réplica del clúster. Si tiene un clúster de instancia única sin instancias de réplica de lectura, el punto de conexión del lector se conecta a la instancia principal, que admite operaciones de escritura. Si el clúster incluye una o varias instancias de réplica de lectura, el envío de una solicitud de escritura al punto de conexión del lector genera una excepción.
+ Cada instancia del clúster también puede tener su propio punto de conexión de instancia. Utilice un punto de conexión de instancia si la aplicación cliente necesita enviar una solicitud a una instancia específica del clúster.

Para obtener más información, consulte [Consideraciones sobre puntos de conexión de Neptune](feature-overview-endpoints.md#feature-overview-endpoint-considerations).

## Coherencia de datos en Neptune
<a name="migration-app-consistency"></a>

Cuando se utilizan clústeres causales de Neo4j, las réplicas de lectura acaban siendo coherentes con los servidores principales, pero las aplicaciones cliente pueden garantizar la coherencia causal mediante el [encadenamiento causal](https://neo4j.com/docs/driver-manual/1.7/sessions-transactions/#driver-transactions-causal-chaining). El encadenamiento causal implica pasar marcadores entre transacciones, lo que permite a una aplicación cliente escribir en un servidor principal y, a continuación, leer su propia escritura desde una réplica de lectura.

En Neptune, las instancias de lectura de réplica son finalmente coherentes con las del escritor, con un retraso de réplica que suele ser inferior a 100 milisegundos. Sin embargo, hasta que se haya replicado un cambio, las actualizaciones de los bordes y vértices existentes y las adiciones de bordes y vértices nuevos no estarán visibles en una instancia de réplica. Por lo tanto, si la aplicación necesita coherencia inmediata en Neptune al leer cada escritura, utilice el punto de conexión del clúster para la operación de lectura después de escritura. Esta es la única vez que se puede usar el punto de conexión del clúster para operaciones de lectura. En todas las demás circunstancias, utilice el punto de conexión del lector para las lecturas.

## Migración de consultas de Neo4j a Neptune
<a name="migration-app-queries"></a>

Si bien la [compatibilidad con openCypher](https://aws.amazon.com/blogs/database/announcing-the-general-availability-of-opencypher-support-for-amazon-neptune/) de Neptune reduce drásticamente la cantidad de trabajo necesaria para migrar las consultas desde Neo4j, aún hay que evaluar algunas diferencias a la hora de migrar:
+ Tal y como se ha mencionado anteriormente en [Optimizaciones de modelos de datos](migration-data-migration.md#migration-data-model-optimization), es posible que deba realizar modificaciones en el modelo de datos para crear un modelo de datos de gráficos optimizado para Neptune, lo que a su vez requerirá cambios en sus consultas y pruebas.
+ Neo4j ofrece una variedad de extensiones de lenguaje específicas de Cypher que no se incluyen en la especificación de openCypher implementada por Neptune. Según el caso de uso y la característica utilizada, puede haber soluciones alternativas en el lenguaje de openCypher, en el lenguaje de Gremlin o mediante otros mecanismos, tal y como se describe en [Reescritura de consultas de Cypher para ejecutarlas en openCypher en Neptune](migration-opencypher-rewrites.md).
+ Las aplicaciones suelen utilizar otros componentes de middleware para interactuar con la base de datos en lugar de los propios controladores Bolt. Eche un vistazo a [Compatibilidad de Neptune con Neo4j](migration-compatibility.md) para ver si las herramientas o el middleware que está utilizando son compatibles.
+ En el caso de una conmutación por error, es posible que el controlador Bolt siga conectándose a la instancia anterior de escritor o lector, ya que el punto de conexión del clúster proporcionado a la conexión se ha resuelto en una dirección IP. Una gestión adecuada de los errores en la aplicación debería solucionar este problema, tal y como se describe en [Cree una nueva conexión después de una conmutación por error](best-practices-opencypher.md#best-practices-opencypher-renew-connection).
+ Cuando las transacciones se cancelan debido a conflictos que no se pueden resolver o a tiempos de espera de bloqueo, Neptune responde con un `ConcurrentModificationException`. Para obtener más información, consulte [Códigos de error del motor](errors-engine-codes.md). Como práctica recomendada, los clientes siempre deben detectar y gestionar estas excepciones.

  En ocasiones, se produce una `ConcurrentModificationException` cuando varios subprocesos o varias aplicaciones escriben en el sistema de forma simultánea. Dados los [niveles de aislamiento de las transacciones](transactions-neptune.md#transactions-neptune-mutation), estos conflictos a veces pueden ser inevitables.
+ Neptune permite ejecutar tanto consultas de Gremlin como de openCypher en los mismos datos. Esto significa que, en algunos casos, puede que tenga que plantearse utilizar Gremlin, con sus capacidades de consulta más potentes, para realizar algunas de las funciones de sus consultas.

Tal y como se ha explicado anteriormente en [Aprovisionamiento de la infraestructura](migration-provisioning-infrastructure.md), cada aplicación debe realizar un ejercicio de dimensionamiento adecuado para garantizar que la cantidad de instancias, los tamaños de las instancias y la topología del clúster estén optimizados para la carga de trabajo específica de la aplicación.

Los aspectos que se tratan aquí para migrar la aplicación son los más comunes, pero esta no es una lista exhaustiva. Cada aplicación es única. Si tiene más preguntas, póngase en contacto con AWS Support o con el equipo de cuentas.

## Migración de características y herramientas específicas de Neo4j
<a name="migration-app-neo4j-specific"></a>

Neo4j tiene una variedad de características y complementos personalizados con una funcionalidad en la que la aplicación puede confiar. Al evaluar la necesidad de migrar esta funcionalidad, suele ser útil investigar si existe un método mejor en AWS para lograr el mismo objetivo. Teniendo en cuenta las [diferencias arquitectónicas entre Neo4j y Neptune](migration-architectural-differences.md), a menudo se pueden encontrar alternativas eficaces que saquen partido de otros servicios de AWS o [integraciones](integrations.md).

Consulte [Compatibilidad de Neptune con Neo4j](migration-compatibility.md) para obtener una lista de las características específicas de Neo4j y las soluciones alternativas sugeridas.

# Compatibilidad de Neptune con Neo4j
<a name="migration-compatibility"></a>

Neo4j se basa en un enfoque integral arquitectónico, en el que la carga de datos, ETL de datos, las consultas a las aplicaciones, el almacenamiento de datos y las operaciones de administración se realizan en el mismo conjunto de recursos informáticos, como, por ejemplo, las instancias EC2. Amazon Neptune es una base de datos de gráficos de especificaciones abiertas y centrada en OLTP en la que la arquitectura separa las operaciones y desacopla los recursos para que puedan escalarse de forma dinámica.

Neo4j incluye diversas características y herramientas, incluidas herramientas de terceros, que no forman parte de la especificación de openCypher, son incompatibles con openCypher o son incompatibles con la implementación de openCypher por Neptune. A continuación, veremos algunas de las más comunes.

## Características específicas de Neo4j que no están presentes en Neptune
<a name="migration-compatibility-features"></a>
+ **`LOAD CSV`**: Neptune tiene un enfoque arquitectónico diferente al de Neo4j para cargar datos. Para permitir una mejor escalabilidad y la optimización de los costos, Neptune implementa una separación de las preocupaciones en torno a los recursos y recomienda utilizar una de las [integraciones de servicios de AWS](integrations.md), como, por ejemplo, AWS Glue para realizar los procesos de ETL necesarios para preparar los datos en un [formato](bulk-load-tutorial-format.md) compatible con el [programa de carga masiva Neptune](bulk-load.md).

  Otra opción es hacer lo mismo con código de aplicación que se ejecute en recursos informáticos de AWS, como instancias de Amazon EC2, funciones de Lambda, Amazon Elastic Container Service, tareas AWS Batch, etc. El código puede usar tanto el [punto de conexión de HTTPS](access-graph-opencypher-queries.md) de Neptune como el [punto de conexión de Bolt](access-graph-opencypher-bolt.md).
+ **Control de acceso detallado**: Neptune admite un control de acceso granular sobre las acciones de acceso a los datos [mediante claves de condición de IAM](iam-data-access-policies.md). Se puede implementar un control de acceso más detallado en la capa de aplicación.
+ **Neo4j Fabric**: Neptune admite la federación de consultas entre bases de datos para cargas de trabajo de RDF mediante la palabra clave [`SERVICE`](sparql-service.md) de SPARQL. Dado que actualmente no existe un estándar o especificación abiertos para la federación de consultas para las cargas de trabajo de gráficos de propiedades, sería necesario implementar esa funcionalidad en la capa de aplicación.
+ **Control de acceso basado en roles (RBAC)**: Neptune administra la autenticación mediante la asignación de [roles y políticas de IAM](iam-auth.md). Los roles y políticas de IAM proporcionan un nivel extremadamente flexible de administración de usuarios dentro de la aplicación, por lo que es importante leer y comprender la [Información general de IAM](iam-auth.md) antes de configurar el clúster.

  
+ **Marcadores**: los clústeres de Neptune constan de una sola instancia de escritor y hasta 15 instancias de réplica de lectura. Los datos escritos en la instancia de escritos son compatibles con ACID y ofrecen una sólida garantía de coherencia en las lecturas posteriores. Las réplicas de lectura utilizan el mismo volumen de almacenamiento que la instancia de escritor y, en última instancia, son coherentes, normalmente en menos de 100 ms desde el momento en que se escriben los datos. Si su caso de uso requiere garantizar inmediatamente la coherencia de lectura de las nuevas escrituras, estas lecturas deben dirigirse al punto de conexión del clúster en lugar de al punto de conexión del lector.
+ **Procedimientos de APOC**: dado que los procedimientos de APOC no están incluidos en la especificación de openCypher, Neptune no proporciona soporte directo para procedimientos externos. En cambio, Neptune se basa en [integraciones con otros servicios de AWS](integrations.md) para lograr una funcionalidad similar para el usuario final de una manera escalable, segura y sólida. A veces, los procedimientos de APOC se pueden volver a escribir en openCypher o Gremlin, y algunos no son relevantes para las aplicaciones de Neptune.

  Por lo general, los procedimientos de APOC se clasifican en las siguientes categorías:
  + **[Importación](https://neo4j.com/labs/apoc/4.2/import/)**: Neptune admite la importación de datos mediante una variedad de formatos mediante lenguajes de consulta, el [programa de carga masiva](bulk-load.md) de Neptune o como destino de [AWS Database Migration Service](dms-neptune.md). Las operaciones de ETL en los datos se pueden realizar mediante AWS Glue y el paquete de código abierto de [https://github.com/awslabs/amazon-neptune-tools/tree/master/neptune-python-utils](https://github.com/awslabs/amazon-neptune-tools/tree/master/neptune-python-utils).
  + **[Exportación](https://neo4j.com/labs/apoc/4.2/export/)**: Neptune admite la exportación de datos mediante la utilidad [`neptune-export`](neptune-data-export.md), que admite una variedad de formatos y métodos de exportación comunes.
  + **[Integración de bases de datos](https://neo4j.com/labs/apoc/4.2/database-integration/)**: Neptune admite la integración con otras bases de datos mediante herramientas de ETL, tales como AWS Glue o herramientas de migración como [AWS Database Migration Service](dms-neptune.md).
  + **[Actualizaciones de gráficos](https://neo4j.com/labs/apoc/4.2/graph-updates/)**: Neptune admite un amplio conjunto de características para actualizar los datos de los gráficos de propiedades mediante su compatibilidad con los lenguajes de consulta de openCypher y Gremlin. Consulte [Reescrituras de Cypher](migration-opencypher-rewrites.md) para ver algunos ejemplos de reescrituras de procedimientos que se usan habitualmente.
  + **[Estructuras de datos](https://neo4j.com/labs/apoc/4.2/data-structures/)**: Neptune admite un amplio conjunto de características para actualizar los datos de los gráficos de propiedades mediante su compatibilidad con los lenguajes de consulta de openCypher y Gremlin. Consulte [Reescrituras de Cypher](migration-opencypher-rewrites.md) para ver algunos ejemplos de reescrituras de procedimientos que se usan habitualmente.
  + **[Temporal (fecha y hora)](https://neo4j.com/labs/apoc/4.2/temporal/)**: Neptune admite un amplio conjunto de características para actualizar los datos de los gráficos de propiedades mediante su compatibilidad con los lenguajes de consulta de openCypher y Gremlin. Consulte [Reescrituras de Cypher](migration-opencypher-rewrites.md) para ver algunos ejemplos de reescrituras de procedimientos que se usan habitualmente.
  + **[Matemática](https://neo4j.com/labs/apoc/4.2/mathematical/)**: Neptune admite un amplio conjunto de características para actualizar los datos de los gráficos de propiedades mediante su compatibilidad con los lenguajes de consulta de openCypher y Gremlin. Consulte [Reescrituras de Cypher](migration-opencypher-rewrites.md) para ver algunos ejemplos de reescrituras de procedimientos que se usan habitualmente.
  + **[Consultas avanzadas de gráficos](https://neo4j.com/labs/apoc/4.2/graph-querying/)**: Neptune admite un amplio conjunto de características para actualizar los datos de los gráficos de propiedades mediante su compatibilidad con los lenguajes de consulta de openCypher y Gremlin. Consulte [Reescrituras de Cypher](migration-opencypher-rewrites.md) para ver algunos ejemplos de reescrituras de procedimientos que se usan habitualmente.
  + **[Comparación de gráficos](https://neo4j.com/labs/apoc/4.2/comparing-graphs/)**: Neptune admite un amplio conjunto de características para actualizar los datos de los gráficos de propiedades mediante su compatibilidad con los lenguajes de consulta de openCypher y Gremlin. Consulte [Reescrituras de Cypher](migration-opencypher-rewrites.md) para ver algunos ejemplos de reescrituras de procedimientos que se usan habitualmente.
  + **[Ejecución de cifrado](https://neo4j.com/labs/apoc/4.2/cypher-execution/)**: Neptune admite un amplio conjunto de características para actualizar los datos de los gráficos de propiedades mediante su compatibilidad con los lenguajes de consulta de openCypher y Gremlin. Consulte [Reescrituras de Cypher](migration-opencypher-rewrites.md) para ver algunos ejemplos de reescrituras de procedimientos que se usan habitualmente.
+ **Procedimientos personalizados**: Neptune no admite procedimientos personalizados creados por los usuarios. Esta funcionalidad tendría que implementarse en la capa de aplicación.
+ **Geoespacial**: aunque Neptune no ofrezca soporte nativo para las características geoespaciales, se puede lograr una funcionalidad similar mediante la integración con otros servicios de AWS, tal y como se muestra en esta publicación del blog: [Combine Amazon Neptune and Amazon OpenSearch Service for geospatial queries](https://aws.amazon.com/blogs/database/combine-amazon-neptune-and-amazon-opensearch-service-for-geospatial-queries/) (Combinación de Amazon Neptune y Amazon OpenSearch Service para consultas geoespaciales) de Ross Gabay y Abhilash Vinod (1 de febrero de 2022).
+ **Ciencia de datos de gráficos**: Neptune actualmente admite el análisis de gráficos a través de [Neptune Analytics](https://docs.aws.amazon.com/neptune-analytics/latest/userguide/what-is-neptune-analytics.html), un motor con optimización de memoria que admite una biblioteca de algoritmos de análisis de gráficos.

  Neptune también proporciona una integración con el [AWS SDK para Pandas](https://github.com/amazon-archives/fully-automated-neo4j-to-neptune) y varios [cuadernos de ejemplo](https://github.com/aws/graph-notebook/tree/main/src/graph_notebook/notebooks/05-Data-Science) que muestran cómo sacar partido de esta integración en los entornos de Python para ejecutar análisis en los datos de gráficos.

  
+ **Restricciones de esquema**: en Neptune, la única restricción de esquema disponible es la exclusividad del identificador de un nodo o un borde. No hay ninguna característica que especifique alguna restricción de esquema adicional ni ninguna restricción adicional de exclusividad o valor en un elemento del gráfico. Los valores de ID en Neptune son cadenas y se pueden configurar con Gremlin, de la siguiente manera:

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

  Se recomienda a las aplicaciones que necesiten sacar partido del ID como una restricción de exclusividad que utilicen este método para lograr una restricción de exclusividad. Si la aplicación utilizó varias columnas como restricción de exclusividad, el ID puede configurarse en una combinación de estos valores. Por ejemplo, `id=123, code='SEA'` podría representarse como `ID='123_SEA'` para lograr una restricción de exclusividad compleja.
+ **Varios inquilinos**: Neptune solo admite un gráfico por clúster. Para crear un sistema de varios inquilinos con Neptune, utilice varios clústeres o divida los inquilinos de forma lógica en un único gráfico y utilice la lógica del lado de la aplicación para reforzar la separación. Por ejemplo, añada una propiedad `tenantId` e inclúyala en cada consulta, como, por ejemplo:

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

  [Neptune sin servidor](neptune-serverless.md) hace que sea relativamente sencillo implementar la opción de varios inquilinos mediante varios clústeres de bases de datos, cada uno de los cuales se escala de forma independiente y automática según sea necesario.

## Soporte de Neptune para las herramientas de Neo4j
<a name="migration-compatibility-tools"></a>

Neptune ofrece las siguientes alternativas a las herramientas de Neo4j:
+ **[Navegador de Neo4j](https://neo4j.com/docs/operations-manual/current/installation/neo4j-browser/)**: Neptune proporciona [cuadernos de gráficos](graph-notebooks.md) de código abierto que proporcionan un IDE centrado en el desarrollador para ejecutar consultas y visualizar los resultados.
+ **[Bloom de Neo4j](https://neo4j.com/product/bloom/)**: Neptune admite visualizaciones detalladas de gráficos mediante [soluciones de visualización de terceros](visualization-tools.md), como Graph-explorer, Tom Sawyer, Cambridge Intelligence, Graphistry, metaphacts y G.V().
+ **[GraphQL](https://graphql.org/)**: Neptune actualmente admite GraphQL a través de integraciones de AWS AppSync personalizadas. Consulte la publicación del 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/) y el proyecto de ejemplo [Building Serverless Calorie tracker application with AWS AppSync and Amazon Neptune](https://github.com/aws-samples/aws-appsync-calorie-tracker-workshop).
+ **[NeoSemantics](https://neo4j.com/labs/neosemantics/4.0/)**: Neptune admite de forma nativa el modelo de datos RDF, por lo que se recomienda a los clientes que deseen ejecutar cargas de trabajo de RDF que utilicen el soporte de modelos RDF de Neptune.
+ **[Arrows.app](https://arrows.app/)**: el cifrado creado al exportar el modelo mediante el comando export es compatible con Neptune.
+ **[Linkurious Ogma](https://doc.linkurious.com/ogma/latest/)**: una integración de ejemplo con Linkurious Ogma está [disponible aquí](https://github.com/aws-samples/amazon-neptune-samples/tree/master/gremlin/ogma-neptune).
+ **[Spring Data Neo4j](https://spring.io/projects/spring-data-neo4j)**: por el momento, esta opción no es compatible con Neptune.
+ **[Conector de Spark de Neo4j](https://neo4j.com/docs/spark/current/)**: el conector de Spark de Neo4j se puede utilizar en un trabajo de Spark para conectarse a Neptune con openCypher. Estos son algunos ejemplos de configuración de códigos y aplicaciones:

  **Código de muestra:**

  ```
  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();
  ```

  **Configuración de aplicaciones:**

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

### Características y herramientas de Neo4j que no se incluyen aquí
<a name="migration-compatibility-tools-unlisted"></a>

Si utiliza una herramienta o característica que no se incluye aquí, no tenemos la certeza de su compatibilidad con Neptune u otros servicios incluidos en AWS. Si tiene más preguntas, póngase en contacto con AWS Support o con el equipo de cuentas.

# Reescritura de consultas de Cypher para ejecutarlas en openCypher en Neptune
<a name="migration-opencypher-rewrites"></a>

El lenguaje de openCypher es un lenguaje de consulta declarativo para gráficos de propiedades que desarrolló originalmente Neo4j y que pasó a ser de código abierto en 2015. Además, contribuyó al [proyecto openCypher](https://www.opencypher.org/) en virtud de una licencia de código abierto Apache 2. En AWS, creemos que el código abierto es bueno para todos y estamos comprometidos a llevar el valor del código abierto a nuestros clientes y la excelencia operativa de AWS las comunidades de código abierto.

OpenCypher La sintaxis está documentada en la [versión 9 de Cypher Query Language Reference](https://s3.amazonaws.com/artifacts.opencypher.org/openCypher9.pdf).

Dado que openCypher incluye un subconjunto de la sintaxis y las características del lenguaje de consultas de Cypher, algunos escenarios de migración requieren reescribir las consultas en formatos compatibles con openCypher o examinar métodos alternativos para lograr la funcionalidad deseada.

En esta sección se incluyen recomendaciones para tratar las diferencias más comunes, pero no es en absoluto exhaustiva. Debe probar minuciosamente cualquier aplicación que utilice estas reescrituras para asegurarse de que los resultados son los previstos.

## Reescritura de funciones de predicado `None`, `All` y `Any`
<a name="migration-opencypher-rewrites-none-all-any"></a>

Estas funciones no forman parte de la especificación de openCypher. Se pueden lograr resultados comparables en openCypher con Comprensión de listas.

Por ejemplo, busque todas las rutas que van del nodo `Start` al nodo `End`, pero no se permite que ningún recorrido atraviese un nodo con una propiedad de clase de `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 opción Comprensión de listas puede lograr los siguientes resultados:

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

## Reescritura de la función `reduce()` de Cypher en openCypher
<a name="migration-opencypher-rewrites-reduce"></a>

La función `reduce()` no forma parte de la especificación de openCypher. Suele utilizarse para crear una agregación de datos a partir de elementos de una lista. En muchos casos, puede utilizar una combinación de Comprensión de listas y la cláusula `UNWIND` para obtener resultados similares.

Por ejemplo, la siguiente consulta de Cypher busca todos los aeropuertos en las rutas que tengan de una a tres paradas entre Anchorage (ANC) y Austin (AUS) y devuelve la distancia total de cada ruta:

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

Puede escribir la misma consulta en openCypher para Neptune, como, por ejemplo:

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

## Reescritura de la cláusula FOREACH de Cypher en openCypher
<a name="migration-opencypher-rewrites-foreach"></a>

La cláusula FOREACH no forma parte de la especificación de openCypher. Suele utilizarse para actualizar los datos en mitad de una consulta, a menudo a partir de agregaciones o elementos de una ruta.

Como ejemplo de ruta, busque todos los aeropuertos de una ruta con no más de dos paradas entre Anchorage (ANC) y Austin (AUS) y establezca una propiedad de visitado en cada una de ellos:

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

Otro ejemplo:

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

## Reescritura de los procedimientos de APOC de Neo4j en Neptune
<a name="migration-opencypher-rewrites-apoc"></a>

Los ejemplos siguientes utilizan openCypher para reemplazar algunos de los [procedimientos de APOC](https://neo4j.com/blog/intro-user-defined-procedures-apoc/) más utilizados. Estos ejemplos son solo de referencia y están destinados a proporcionar algunas sugerencias sobre cómo gestionar situaciones comunes. En la práctica, cada aplicación es diferente y tendrá que idear sus propias estrategias para proporcionar toda la funcionalidad que necesite.

### Reescritura de los procedimientos de `apoc.export`
<a name="migration-opencypher-rewrites-apoc-export"></a>

Neptune ofrece una variedad de opciones para exportaciones completas basadas en consultas y gráficos en varios formatos de salida, como CSV y JSON, mediante la utilidad [neptune-export](https://github.com/aws/neptune-export) (consulte [Exportación de datos desde un clúster de base de datos de Neptune](neptune-data-export.md)).

### Reescritura de los procedimientos de `apoc.schema`
<a name="migration-opencypher-rewrites-apoc-schema"></a>

Neptune no tiene esquemas, índices ni restricciones definidos de forma explícita, por lo que muchos procedimientos de `apoc.schema` ya no son necesarios. Algunos ejemplos son:
+ `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`

openCypher de Neptune admite la recuperación de valores similares a los de los procedimientos, tal y como se muestra a continuación, pero puede tener problemas de rendimiento en gráficos de mayor tamaño, ya que para ello es necesario escanear una gran parte del gráfico con el fin de obtener la respuesta.

```
# 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)
```

### Alternativas a los procedimientos de `apoc.do`
<a name="migration-opencypher-rewrites-apoc-do"></a>

Estos procedimientos se utilizan para proporcionar una ejecución de consultas condicional que sea fácil de implementar con otras cláusulas de openCypher. En Neptune hay al menos dos formas de lograr un comportamiento similar:
+ Una forma es combinar las capacidades de Comprensión de listas de openCypher con la cláusula `UNWIND`.
+ Otra forma es usar los pasos choose() y coalesce() de Gremlin.

A continuación se muestran ejemplos de estos enfoques.

#### Alternativas a 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())
```

#### Alternativas a 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())
```

## Alternativas a las propiedades basadas en listas
<a name="migration-opencypher-rewrites-lists"></a>

Neptune no admite actualmente el almacenamiento de propiedades basadas en listas. Sin embargo, se pueden obtener resultados similares si se almacenan los valores de la lista como una cadena separada por comas y, a continuación, se utilizan las funciones `join()` y `split()` para construir y deconstruir la propiedad de la lista.

Por ejemplo, si quisiéramos guardar una lista de etiquetas como una propiedad, podríamos usar el ejemplo de reescritura, que muestra cómo recuperar una propiedad separada por comas, y luego usar las funciones `split()` y `join()` con Compresión de listas para lograr resultados 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
```

## Reescritura de subconsultas CALL
<a name="migration-opencypher-rewrites-call-subqueries"></a>

 Las subconsultas `CALL` de Neptune no admiten la sintaxis `CALL (friend) { ... }` para importar variables al ámbito de la subconsulta (`friend`, en este ejemplo). Utilice la cláusula `WITH` incluida en la subconsulta para hacer lo mismo, por ejemplo, `CALL { WITH friend ... }`. 

 Las subconsultas `CALL` opcionales no se admiten en este momento. 

## Otras diferencias entre openCypher de Neptune y Cypher
<a name="opencypher-compliance-other-differences"></a>
+ Neptune solo admite conexiones TCP para el protocolo Bolt. WebSocketsno se admiten las conexiones para Bolt.
+ openCypher de Neptune elimina los espacios en blanco tal como los define Unicode en las funciones `trim()`, `ltrim()` y `rtrim()`.
+ En openCypher de Neptune, `tostring(`double`)` no cambia automáticamente a la notación E para valores grandes del doble.

# Recursos para migrar de Neo4j a Neptune
<a name="migration-resources"></a>

Neptune proporciona varias herramientas y recursos que pueden ayudar en el proceso de migración.

**Herramientas para ayudar a migrar de Neo4j a Neptune**
+ El 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): una utilidad de línea de comandos para migrar datos de Neo4j a Neptune. Esta herramienta incluye la capacidad de:
  + Exportar los datos de un gráfico Neo4j correctamente configurado.
  + Convierte esos datos al formato de Neptune.
  + Carga masivamente esos datos en Neptune.
  + Realice algunas conversiones básicas de datos durante la conversión al formato de Neptune, como cambiar el nombre de las etiquetas de vértices o bordes y generar elementos.
  + Genere propiedades para los nodos y los bordes mediante plantillas (por ejemplo, cree un `~id` valor con una plantilla, `Person_{personid}` por ejemplo, en situaciones en las que necesite crear el identificador único de un elemento).
+ [Comprobador de compatibilidad de consultas de OpenCypher](https://github.com/awslabs/amazon-neptune-tools/tree/master/opencypher-compatability-checker): esta herramienta toma una entrada de las consultas de OpenCypher y:
  + Comprueba la compatibilidad con la versión seleccionada de Neptune.
  + Identifique las funciones y cláusulas específicas no compatibles con sus posiciones.
  + Sugiera reemplazos si están disponibles.
  + Proporcione descripciones de los errores de cualquier otro error de sintaxis.