

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

# Migrar do Neo4j para o Amazon Neptune
<a name="migrating-from-neo4j"></a>

O Neo4j e o Amazon Neptune são bancos de dados de grafos projetados para workloads de grafos transacionais on-line que são compatíveis com o modelo de dados de grafos de propriedades rotulado. Essas semelhanças tornam o Neptune uma escolha comum para clientes que desejam migrar as aplicações Neo4j atuais. No entanto, essas migrações não são simples procedimentos de mover sem alterações (lift-and-shift), pois há diferenças no suporte a linguagens e atributos, nas características operacionais, na arquitetura do servidor e nos recursos de armazenamento entre os dois bancos de dados.

Esta página explica o processo de migração e aborda aspectos a serem considerados antes de migrar uma aplicação de grafos Neo4j para o Neptune. Essas considerações geralmente se aplicam a qualquer aplicação de grafos Neo4j, seja alimentada por um banco de dados Community, Enterprise ou Aura. Embora cada solução seja exclusiva e possa exigir procedimentos adicionais, todas as migrações seguem o mesmo padrão geral.

Cada uma das etapas descritas nas seções a seguir inclui considerações e recomendações para simplificar o processo de migração. Além disso, há [ferramentas de código aberto e postagens no blog](migration-resources.md) que descrevem o processo e uma [seção sobre compatibilidade de atributos](migration-compatibility.md) com opções de arquitetura recomendadas.

**Topics**
+ [Informações gerais sobre a migração do Neo4j para o Neptune](migrating-from-neo4j-general.md)
+ [Preparar-se para migrar do Neo4j para o Neptune](preparing-to-migrate-from-neo4j.md)
+ [Provisionar infraestrutura ao migrar do Neo4j para o Neptune](migration-provisioning-infrastructure.md)
+ [Migração de dados do Neo4j para o Neptune](migration-data-migration.md)
+ [Migração de aplicações do Neo4j para o Neptune](migration-app-migration.md)
+ [Compatibilidade do Neptune com o Neo4j](migration-compatibility.md)
+ [Reformular consultas do Cypher para serem executadas no openCypher no Neptune](migration-opencypher-rewrites.md)
+ [Recursos para migrar do Neo4j para o Neptune](migration-resources.md)

# Informações gerais sobre a migração do Neo4j para o Neptune
<a name="migrating-from-neo4j-general"></a>

Com o [suporte para a linguagem de consulta openCypher](feature-opencypher-compliance.md), você pode mover a maioria das workloads do Neo4j que usam o protocolo Bolt ou HTTPS para o Neptune. No entanto, o openCypher é uma especificação de código aberto que contém a maioria, mas não todas, as funcionalidades compatíveis com outros bancos de dados, como o Neo4j.

Apesar de ser compatível de várias maneiras, o Neptune não é um substituto imediato do Neo4j. O Neptune é um serviço de banco de dados de grafos totalmente gerenciado com atributos corporativos, como alta disponibilidade e alta durabilidade, que é arquitetonicamente diferente do Neo4j. O Neptune é baseado em instâncias, com uma única instância de gravador principal e até 15 instâncias de réplica de leitura que permitem escalar a capacidade de leitura horizontalmente. Usando o [Neptune Serverless](neptune-serverless.md), é possível aumentar ou reduzir a escala da capacidade computacional verticalmente, dependendo do volume de consultas. Isso é independente do armazenamento do Neptune, que é escalado automaticamente à medida que você adiciona dados.

O Neptune é compatível com a [especificação padrão do openCypher de código aberto, versão 9](https://s3.amazonaws.com/artifacts.opencypher.org/openCypher9.pdf). Na AWS, acreditamos que o código aberto é bom para todos e estamos comprometidos em trazer o valor do código aberto aos nossos clientes e em levar a excelência operacional das AWS comunidades de código aberto.

No entanto, muitas aplicações executadas no Neo4j também usam atributos exclusivos que não são de código aberto e que o Neptune não aceita. Por exemplo, o Neptune não é compatível com procedimentos APOC, algumas cláusulas e funções específicas do Cypher e os tipos de dados `Char`, `Date` e `Duration`. O Neptune converte automaticamente os tipos de dados ausentes em [tipos de dados compatíveis](bulk-load-tutorial-format-opencypher.md#bulk-load-tutorial-format-opencypher-data-types).

Além do OpenCypher, o Neptune também suporta a linguagem de consulta [Apache TinkerPop Gremlin](https://tinkerpop.apache.org/docs/current/reference/#traversal) para gráficos de propriedades (bem como SPARQL para dados RDF). O Gremlin pode interoperar com o openCypher no mesmo grafo de propriedades e, em muitos casos, é possível usar o Gremlin para fornecer funcionalidades não oferecidas pelo openCypher. Veja uma comparação rápida das duas linguagens:


|  | openCypher | Gremlin | 
| --- | --- | --- | 
| Estilo | Declarativa | Imperativa | 
| Sintaxe |  Correspondência de padrão <pre>Match p=(a)-[:route]->(d)<br />WHERE a.code='ANC'<br />RETURN p<br /></pre>  |  Baseada em percurso <pre>g.V().has('code', 'ANC').<br />out('route').path().<br />by(elementMap())</pre>  | 
| Facilidade de uso | Inspirada em SQL, legível por não programadores | Curva de aprendizado mais íngreme, semelhante a linguagens de programação como Java | 
| Flexibilidade | Baixo | Alto | 
| Compatível com consultas | Consultas baseadas em strings | Consultas baseadas em strings ou código em linha compatíveis com bibliotecas de cliente | 
| Clientes | HTTPS e Bolt | HTTPS e Websockets | 

Em geral, não é necessário alterar o modelo de dados para migrar do Neo4j para o Neptune, porque tanto o Neo4j quanto o Neptune são compatíveis com dados de grafos de propriedades rotulados (LPG). No entanto, o Neptune tem algumas diferenças de arquitetura e modelo de dados que você pode aproveitar para otimizar o desempenho. Por exemplo:
+  IDs Netuno é tratado como cidadão de primeira classe.
+ O Neptune usa [políticas do AWS Identity and Access Management (IAM)](iam-auth.md) para proteger o acesso aos dados de grafos de forma flexível e granular.
+ O Neptune oferece várias maneiras de [usar os cadernos Jupyter](graph-notebooks.md) para executar consultas e [visualizar os resultados](notebooks-visualization.md). O Neptune também trabalha com [ferramentas de visualização de terceiros](visualization-tools.md).
+ Embora o Neptune não tenha um substituto imediato para a biblioteca Neo4j Graph Data Science (GDS), no momento, ele é compatível com a análise de grafos por meio de uma variedade de soluções. Por exemplo, vários [notebooks de amostra](https://github.com/aws/graph-notebook/tree/main/src/graph_notebook/notebooks/01-Neptune-Database/03-Sample-Applications/06-Data-Science-Samples) demonstram como aproveitar a [integração do Neptune com o SDK do AWS Pandas em ambientes Python para executar](https://github.com/amazon-archives/fully-automated-neo4j-to-neptune) análises em dados gráficos.

Entre em contato com o AWS suporte ou entre em contato com a equipe de sua AWS conta se tiver dúvidas. Usamos seus comentários para priorizar novos atributos que atendam às suas necessidades.

# Preparar-se para migrar do Neo4j para o Neptune
<a name="preparing-to-migrate-from-neo4j"></a>

 A migração do banco de dados de grafos Neo4j para o serviço de banco de dados de grafos do Neptune pode ser abordada de duas maneiras: reformulação de plataforma ou refatoração/rearquitetura. A abordagem de reformulação de plataforma envolve modificar o modelo de dados e a arquitetura de aplicação existentes para melhor aproveitar os recursos do Neptune, enquanto a abordagem de refatoração se concentra em encontrar componentes equivalentes no Neptune para criar uma implementação comparável. Na prática, frequentemente se usa uma combinação dessas estratégias, pois o processo de migração envolve equilibrar a arquitetura do Neptune de destino com restrições e requisitos da implementação existente do Neo4j. Independentemente da abordagem, é fundamental trabalhar retroativamente a partir dos casos de uso da aplicação para projetar o modelo de dados, as consultas e a arquitetura geral que melhor atendam às suas necessidades. 

## Abordagens da migração
<a name="migration-approaches"></a>

Ao migrar uma aplicação Neo4j para o Neptune, recomendamos uma das duas estratégias: reformulação da plataforma ou refatoração/rearquitetura. Para obter mais informações sobre estratégias de migração, consulte [6 Strategies for Migrating Applications to the Cloud](https://aws.amazon.com/blogs/enterprise-strategy/6-strategies-for-migrating-applications-to-the-cloud/), uma postagem no blog de Stephen Orban.

A *abordagem de reestruturação de plataformas*, às vezes chamada *lift-tinker-and-shift*, envolve as seguintes etapas:
+ Identifique os casos de uso que a aplicação pretende satisfazer.
+ Modifique o modelo de dados de grafos e a arquitetura de aplicações existentes para melhor atender a essas necessidades de workload usando os recursos do Neptune.
+ Determine como migrar dados, consultas e outras partes da aplicação de origem para o modelo e a arquitetura de destino.

Essa abordagem retroativa permite migrar a aplicação para o tipo de solução do Neptune que você pode criar se esse fosse um projeto totalmente novo.

A *abordagem de refatoração*, por outro lado, envolve:
+ Identificar os componentes da implementação existente, incluindo infraestrutura, dados, consultas e recursos de aplicações.
+ Encontrar equivalentes no Neptune que possam ser usados para criar uma implementação comparável.

Essa abordagem progressiva busca trocar uma implementação por outra.

Na prática, é provável que você adote uma combinação dessas duas abordagens. É possível começar com um caso de uso, projetar a arquitetura do Neptune de destino, mas depois recorrer à implementação existente do Neo4j para identificar restrições e invariantes que você precisará manter. Por exemplo, talvez você precise continuar a integração com outros sistemas externos ou continuar oferecendo produtos específicos APIs para consumidores do seu aplicativo gráfico. Com essas informações, é possível determinar quais dados já existem para serem migrados para o modelo de destino e quais devem ser obtidos em outro lugar.

Em outros pontos, você pode começar analisando uma parte específica da implementação do Neo4j como a melhor fonte de informações sobre o trabalho que a aplicação se destina a realizar. Esse tipo de arqueologia na aplicação existente pode ajudar a definir um caso de uso que você pode depois projetar para usar os recursos do Neptune.

Se você estiver criando uma aplicação usando o Neptune ou migrando uma aplicação existente do Neo4j, recomendamos trabalhar retroativamente a partir dos casos de uso para criar um modelo de dados, um conjunto de consultas e uma arquitetura de aplicações que atenda às necessidades empresariais.

# Diferenças arquitetônicas entre o Neptune e o Neo4j
<a name="migration-architectural-differences"></a>

Quando os clientes consideram pela primeira vez migrar um aplicativo do Neo4j para o Neptune, geralmente é tentador fazer uma comparação com base no tamanho da instância. like-to-like No entanto, as arquiteturas do Neo4j e do Neptune têm diferenças fundamentais. O Neo4j é baseado em uma all-in-one abordagem em que o carregamento de dados, o ETL de dados, as consultas de aplicativos, o armazenamento de dados e as operações de gerenciamento acontecem no mesmo conjunto de recursos computacionais, como instâncias do EC2.

O Neptune, por outro lado, é um banco de dados de grafos focado em OLTP em que a arquitetura separa as responsabilidades e onde os recursos são dissociados para que possam ser escalados de forma dinâmica e independente.

Ao migrar do Neo4j para o Neptune, determine os requisitos de durabilidade, disponibilidade e escalabilidade dos dados da aplicação. A arquitetura de cluster do Neptune simplifica o design de aplicações que exigem alta durabilidade, disponibilidade e escalabilidade. Com uma compreensão da arquitetura de cluster do Neptune, é possível então projetar uma topologia de cluster do Neptune para atender a esses requisitos.

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

Muitas aplicações de produção usam o [agrupamento causal](https://neo4j.com/docs/operations-manual/current/clustering/introduction/) do Neo4j para oferecer durabilidade de dados, alta disponibilidade e escalabilidade. A arquitetura de agrupamento do Neo4j usa instâncias de servidor central e de réplica de leitura:
+ Os servidores centrais oferecem durabilidade de dados e tolerância a falhas replicando dados com o protocolo Raft.
+ As réplicas de leitura usam o envio de logs de transações para replicar dados de forma assíncrona para workloads de alta taxa de throughput de leitura.

Cada instância em um cluster, seja servidor central ou réplica de leitura, contém uma cópia completa dos dados de grafos.

## Arquitetura do cluster do Neptune
<a name="migration-neptune-cluster-architecture"></a>

[Um cluster do Neptune](feature-overview-db-clusters.md) é composto por uma instância de gravador principal e até 15 instâncias de réplica de leitura. Todas as instâncias no cluster compartilham o mesmo serviço de armazenamento distribuído subjacente que é separado das instâncias.
+ A instância de gravador principal coordena todas as operações de gravação no banco de dados e é escalável verticalmente para oferecer suporte flexível para diferentes workloads de gravação. Ela também é compatível com operações de leitura.
+ As instâncias de réplica de leitura são compatíveis com operações de leitura do volume de armazenamento subjacente e permitem que você escale horizontalmente para suportar altas workloads de leitura. Elas também oferecem alta disponibilidade servindo como destinos de failover para a instância principal.
**nota**  
Para workloads de gravação pesadas, é melhor escalar as instâncias da réplica de leitura para o mesmo tamanho da instância de gravador, a fim de garantir que os leitores possam permanecer consistentes com as alterações dos dados.
+ O volume de armazenamento subjacente escala a capacidade de armazenamento automaticamente à medida que os dados no banco de dados aumentam, até 128 tebibytes (TiB) de armazenamento.

Os tamanhos das instâncias são dinâmicos e independentes. Enquanto o cluster estiver em execução, todas as instâncias poderão ser redimensionadas e as réplicas de leitura poderão ser adicionadas ou removidas.

O atributo [Neptune Serverless](neptune-serverless.md) pode aumentar e reduzir verticalmente a escala da capacidade computacional de modo automático à medida que a demanda aumenta e diminui. Isso não só pode diminuir a sobrecarga administrativa, mas também permite configurar o banco de dados para lidar com grandes picos de demanda sem prejudicar o desempenho nem exigir provisionamento excessivo.

É possível interromper um cluster de banco de dados por até sete dias.

O Neptune também é compatível com o [ajuste de escala automático](manage-console-autoscaling.md), para ajustar automaticamente os tamanhos das instâncias de leitor com base na workload.

Usando o [atributo de banco de dados global](neptune-global-database.md) do Neptune, é possível espelhar um cluster em até cinco outras regiões.

O Neptune também é [tolerante a falhas por design](backup-restore-overview-fault-tolerance.md):
+ O volume do cluster que fornece armazenamento de dados para todas as instâncias no cluster abrange várias zonas de disponibilidade (AZs) em uma única Região da AWS. Cada AZ contém uma cópia completa dos dados do cluster.
+ Se a instância principal ficar indisponível, o Neptune automaticamente fará failover para uma réplica de leitura existente sem perda de dados, normalmente em menos de trinta segundos. Se não houver réplicas de leitura existentes no cluster, o Neptune provisionará automaticamente uma nova instância principal: novamente, sem perda de dados.

O que tudo isso significa é que, ao migrar de um cluster causal do Neo4j para o Neptune, você não precisa arquitetar a topologia do cluster explicitamente para obter alta durabilidade e alta disponibilidade dos dados. Isso permite dimensionar o cluster para as workloads de leitura e gravação esperadas e todos os requisitos de maior disponibilidade que você possa ter, de apenas algumas maneiras:
+ Para escalar as operações de leitura, [adicione instâncias de réplica de leitura](feature-overview-db-clusters.md#feature-overview-read-replicas) ou habilite a funcionalidade [Neptune Serverless](neptune-serverless.md).
+ Para melhorar a disponibilidade, distribua a instância primária e leia as réplicas em seu cluster em várias zonas de disponibilidade (AZs).
+ Para reduzir o tempo de failover, provisione pelo menos uma instância de réplica de leitura que possa servir como destino de failover para a principal. É possível determinar a ordem em que as instâncias de réplica de leitura são promovidas à instância principal após uma falha, [atribuindo uma prioridade a cada réplica](manage-console-add-replicas.md). É uma prática recomendada garantir que um destino de failover tenha uma classe de instância capaz de lidar com a workload de gravação da aplicação se for promovido para principal.

# Diferenças de armazenamento de dados entre o Neptune e o Neo4j
<a name="migration-storage-differences"></a>

O Neptune usa um [modelo de dados de grafos](feature-overview-data-model.md) baseado em um modelo quádruplo nativo. Ao migrar os dados para o Neptune, há algumas diferenças na arquitetura do modelo de dados e da camada de armazenamento que você deve conhecer para fazer o melhor uso do armazenamento compartilhado distribuído e escalável que o Neptune oferece:
+ O Neptune não usa nenhum esquema explicitamente definido nem restrições. Ele permite que você adicione nós, bordas e propriedades dinamicamente sem precisar definir o esquema com antecedência. O Neptune não limita os valores e os tipos de dados armazenados, exceto conforme indicado em [Limites do Neptune](limits.md#limits-properties). Como parte da arquitetura de armazenamento do Neptune, os dados também são [indexados automaticamente](feature-overview-storage-indexing.md) de forma a lidar com muitos dos padrões de acesso mais comuns. Essa arquitetura de armazenamento elimina a sobrecarga operacional da criação e do gerenciamento do esquema do banco de dados e da otimização do índice.
+ O Neptune oferece uma arquitetura exclusiva de armazenamento distribuído e compartilhado que é escalada automaticamente em blocos de 10 GB à medida que as necessidades de armazenamento do banco de dados aumentam, até 128 tebibytes (TiB). Essa camada de armazenamento é confiável, durável e tolerante a falhas, com dados copiados seis vezes, duas vezes em cada uma das três zonas de disponibilidade. Por padrão, ele oferece a todos os clusters do Neptune uma camada de armazenamento de dados altamente disponível e tolerante a falhas. A arquitetura de armazenamento do Neptune reduz os custos e elimina a necessidade de provisionar ou provisionar em excesso o armazenamento para lidar com o crescimento futuro dos dados.

Antes de migrar os dados para o Neptune, é bom conhecer o [modelo de dados de grafos de propriedades](feature-overview-storage-indexing.md#feature-overview-storage-indexing-gremlin) e a [semântica das transações](transactions.md) do Neptune. 

# Diferenças operacionais entre o Neptune e o Neo4j
<a name="migration-operational-differences"></a>

O Neptune é um serviço totalmente gerenciado que automatiza muitas das tarefas operacionais normais que você precisaria realizar ao usar bancos de dados on-premises ou autogerenciados, como Neo4j Enterprise ou Community Edition:
+ **[Backups automatizados](backup-restore.md#backup-restore-overview-backups)**: o Neptune faz backup automático do volume do cluster e retém o backup por um período de retenção especificado por você (de um a 35 dias). Esses backups são contínuos e incrementais para que você possa restaurar rapidamente em qualquer ponto do período de retenção. Quando os dados do backup estão sendo gravados, não há nenhum impacto sobre a performance ou interrupção de serviço do banco de dados.
+ **[Snapshots manuais](backup-restore.md)**: o Neptune permite que você faça um snapshot do volume de armazenamento do cluster de banco de dados para fazer backup de todo o cluster de banco de dados. Esse tipo de snapshot pode então ser usado para restaurar o banco de dados, fazer uma cópia dele e compartilhá-lo entre contas.
+ **[Clonagem](manage-console-cloning.md)**: o Neptune é compatível com um atributo de clonagem que permite criar clones econômicos de um banco de dados com rapidez. Os clones usam um copy-on-write protocolo para exigir apenas um mínimo de espaço adicional após serem criados. A clonagem de banco de dados é uma forma eficaz de testar novos atributos ou atualizações do Neptune sem interromper o cluster de origem.
+ **[Monitoramento](monitoring.md)**: o Neptune oferece vários métodos para monitorar o desempenho e o uso do cluster, incluindo:
  + Status da instância
  + Integração com a Amazon CloudWatch e AWS CloudTrail
  + Recursos de log de auditoria
  + Notificações de eventos
  + Tags
+ **[Segurança](security.md)**: o Neptune oferece um ambiente seguro por padrão. Um cluster reside em uma VPC privada que oferece isolamento de rede de outros recursos. Todo o tráfego é criptografado via SSL e todos os dados são criptografados em repouso usando AWS KMS.

  [Além disso, o Neptune se integra ao (IAM) para AWS Identity and Access Management fornecer autenticação.](iam-auth.md) Ao especificar as [chaves de condição do IAM](iam-condition-keys.md), é possível usar as políticas do IAM para oferecer controle de acesso refinado sobre as [ações de dados](iam-data-access-policies.md).

## Diferenças de ferramentas e integração entre o Neptune e o Neo4j
<a name="migration-tooling-differences"></a>

O Neptune tem uma arquitetura para integrações e ferramentas diferente do Neo4j, o que pode afetar a arquitetura da aplicação. O Neptune usa os recursos computacionais do cluster para processar consultas, mas aproveita best-in-class AWS outros serviços para obter funcionalidades como pesquisa de texto completo (usando OpenSearch), ETL (usando Glue) e assim por diante. Para obter uma lista completa dessas integrações, consulte [Integrações do Neptune](integrations.md).

# Provisionar infraestrutura ao migrar do Neo4j para o Neptune
<a name="migration-provisioning-infrastructure"></a>

Os clusters do Amazon Neptune são criados para serem escalados em três dimensões: armazenamento, capacidade de gravação e capacidade de leitura. As seções abaixo abordam opções específicas a serem consideradas ao migrar.

## Provisionar armazenamento
<a name="migration-provisioning-storage"></a>

O armazenamento de qualquer cluster do Neptune é provisionado automaticamente, sem nenhuma sobrecarga administrativa de sua parte. Ele é redimensionado dinamicamente em blocos de 10 GB à medida que as necessidades de armazenamento do cluster aumentam. Como resultado, não há necessidade de estimar e provisionar ou provisionar em excesso o armazenamento para lidar com o crescimento futuro dos dados.

## Provisionar a capacidade de gravação
<a name="migration-provisioning-write-capacity"></a>

O Neptune oferece uma única instância de gravador que pode ser escalada verticalmente para qualquer tamanho de instância disponível na [página Preços do Neptune](https://aws.amazon.com/neptune/pricing/). Ao ler e gravar dados em uma instância de gravador, todas as transações são compatíveis com ACID, com isolamento de dados conforme definido em [Níveis de isolamento de transação no Neptune](transactions-neptune.md).

A escolha de um tamanho ideal de uma instância de gravador exige a execução de testes de carga para determinar o tamanho ideal da instância para a workload. Qualquer instância no Neptune pode ser redimensionada a qualquer momento [modificando a classe da instância de banco de dados](manage-console-instances-modify.md). É possível estimar o tamanho da instância inicial com base na simultaneidade e na latência média da consulta, conforme descrito abaixo em [Estimar o tamanho ideal da instância ao provisionar o cluster](#migration-provisioning-instance-sizing).

## Provisionar a capacidade de leitura
<a name="migration-provisioning-read-capacity"></a>

O Neptune foi criado para escalar instâncias de réplica de leitura horizontalmente, adicionando até 15 delas a um cluster (ou mais em um [banco de dados global do Neptune](neptune-global-database.md)) e verticalmente a qualquer tamanho de instância disponível na [página Preços do Neptune](https://aws.amazon.com/neptune/pricing/). Todas as instâncias de réplica de leitura do Neptune usam o mesmo volume de armazenamento subjacente, permitindo a replicação transparente dos dados com o mínimo de atraso.

Além de permitir a escalabilidade horizontal das solicitações de leitura em um cluster do Neptune, as réplicas de leitura também atuam como destinos de failover para a instância de gravador a fim de permitir alta disponibilidade. Consulte [Diretrizes operacionais básicas do Amazon Neptune](best-practices-general-basic.md) para obter sugestões sobre como determinar o número e o posicionamento apropriados das réplicas de leitura no cluster.

Para aplicações em que a conectividade e a workload sejam imprevisíveis, o Neptune também é compatível com [um atributo de ajuste de escala automático](manage-console-autoscaling.md) que pode ajustar automaticamente o número de réplicas do Neptune com base nos critérios especificados.

Para determinar o tamanho e o número ideais das instâncias de réplica de leitura, é necessário realizar testes de carga para determinar as características da workload de leitura que elas devem aceitar. Qualquer instância no Neptune pode ser redimensionada a qualquer momento [modificando a classe da instância de banco de dados](manage-console-instances-modify.md). É possível estimar o tamanho da instância inicial com base na simultaneidade e na latência média da consulta, conforme descrito na [próxima seção](#migration-provisioning-instance-sizing).

## Use o Neptune Serverless para escalar instâncias de leitura e gravação automaticamente, conforme necessário
<a name="migration-provisioning-serverless"></a>

Embora muitas vezes seja útil poder estimar a capacidade computacional que as workloads previstas exigirão, você pode configurar o atributo [Neptune Serverless](neptune-serverless.md) para aumentar e reduzir verticalmente a escala da capacidade de leitura e gravação de modo automático. Isso pode ajudar você a atender aos requisitos de pico e, ao mesmo tempo, reduzir automaticamente quando a demanda diminui.

## Estimar o tamanho ideal da instância ao provisionar o cluster
<a name="migration-provisioning-instance-sizing"></a>

A estimativa do tamanho ideal da instância exige conhecer a latência média da consulta no Neptune, quando a workload está em execução, bem como o número de consultas simultâneas processadas. Uma estimativa aproximada do tamanho da instância pode ser calculada como a latência média da consulta multiplicada pelo número de consultas simultâneas. Isso fornece o número médio de threads simultâneos necessários para lidar com a workload.

[Cada vCPU em uma instância do Neptune pode suportar dois encadeamentos de consulta simultâneos, portanto, dividir os encadeamentos por 2 fornece o número de v CPUs necessário, que pode ser correlacionado ao tamanho apropriado da instância na página de preços do Neptune.](https://aws.amazon.com/neptune/pricing/) Por exemplo:

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

Correlacionando isso com o número de v CPUs em uma instância, vemos que obtemos uma estimativa aproximada de que a `r5.4xlarge` seria a instância recomendada para testar essa carga de trabalho. Essa estimativa é aproximada e serve apenas para oferecer orientação inicial sobre a seleção do tamanho da instância. Qualquer aplicação deve passar por um exercício de dimensionamento correto para determinar o número e os tipos apropriados de instâncias adequadas à workload.

Os requisitos de memória também devem ser levados em consideração, assim como os requisitos de processamento. O Neptune tem melhor desempenho quando os dados acessados pelas consultas estão disponíveis no cache do grupo de buffer da memória principal. Provisionar memória suficiente também pode reduzir significativamente I/O os custos.

Mais detalhes e orientações sobre o dimensionamento de instâncias em um cluster do Neptune podem ser encontrados na página [Dimensionar instâncias de banco de dados em um cluster de banco de dados do Neptune](feature-overview-db-clusters.md#feature-overview-sizing-instances).

# Migração de dados do Neo4j para o Neptune
<a name="migration-data-migration"></a>

Ao realizar uma migração do Neo4j para o Amazon Neptune, a migração dos dados é uma etapa importante do processo. Há várias abordagens para migrar dados. A abordagem correta é determinada pelas necessidades da aplicação, pelo tamanho dos dados e pelo tipo de migração desejada. No entanto, muitas dessas migrações exigem a avaliação das mesmas considerações, das quais várias são destacadas abaixo.

**nota**  
Consulte [Migrating a Neo4j graph database to Neptune with a fully automated utility](https://aws.amazon.com/blogs/database/migrating-a-neo4j-graph-database-to-amazon-neptune-with-a-fully-automated-utility/) no [blog do banco de dados da AWS](https://aws.amazon.com/blogs/?awsf.blog-master-category=category%23database) para obter uma explicação passo a passo completa de um exemplo de como realizar uma migração de dados off-line.

## Avaliar a migração de dados do Neo4j para o Neptune
<a name="migration-data-assessment"></a>

A primeira etapa ao avaliar qualquer migração de dados é determinar como você migrará os dados. As opções dependem da arquitetura da aplicação que está sendo migrada, do tamanho dos dados e das necessidades de disponibilidade durante a migração. Em geral, as migrações tendem a se enquadrar em uma das duas categorias: on-line ou off-line.

As migrações off-line tendem a ser as mais simples de realizar, porque a aplicação não aceita tráfego de leitura ou gravação durante a migração. Depois que a aplicação parar de aceitar tráfego, os dados poderão ser exportados, otimizados, importados e a aplicação testada antes de ser reabilitada.

As migrações on-line são mais complexas, pois a aplicação ainda precisa aceitar tráfego de leitura e gravação enquanto os dados estão sendo migrados. As necessidades exatas de cada migração on-line podem ser diferentes, mas geralmente a arquitetura seria semelhante à seguinte:
+ Um feed de alterações contínuas no banco de dados precisa ser habilitado no Neo4j configurando os [fluxos do Neo4j como fonte para um cluster do Kafka](https://neo4j.com/labs/kafka/4.0/producer/).
+ Depois que isso for concluído, uma exportação do sistema em execução poderá ser feita, seguindo as instruções em [Exportar dados do Neo4j ao migrar para o Neptune](#migration-data-exporting) e o horário indicado para correlação posterior com o tópico do Kafka.
+ Os dados exportados são então importados para o Neptune, seguindo as instruções em [Importar dados do Neo4j ao migrar para o Neptune](#migration-data-importing).
+ Os dados alterados dos fluxos do Kafka podem então ser copiados no cluster do Neptune usando uma arquitetura semelhante à descrita em [Writing to Amazon Neptune from Amazon Kinesis Data Streams](https://github.com/aws-samples/amazon-neptune-samples/tree/master/gremlin/stream-2-neptune). Observe que a replicação das alterações pode ser executada paralelamente para validar a arquitetura e o desempenho da nova aplicação.
+ Depois que a migração de dados for validada, o tráfego da aplicação poderá ser redirecionado para o cluster do Neptune e a instância do Neo4j poderá ser desativada.

## Otimizações de modelos de dados para migrar do Neo4j para o Neptune
<a name="migration-data-model-optimization"></a>

Tanto o Neptune quanto o Neo4j são compatíveis com grafos de propriedades rotulados (LPG). No entanto, o Neptune tem algumas diferenças de arquitetura e modelo de dados que você pode aproveitar para otimizar o desempenho:

### Otimizar IDs de nós e bordas
<a name="migration-data-node-edge-id-optimization"></a>

O Neo4j gera automaticamente IDs numéricos longos. Usando o Cypher, é possível se referir aos nós por ID, mas isso geralmente é desencorajado priorizando-se a pesquisa de nós por uma propriedade indexada.

O Neptune permite [fornecer os próprios IDs baseados em strings para vértices e bordas](access-graph-gremlin-differences.md#feature-gremlin-differences-user-supplied-ids). Se você não fornecer os próprios IDs, o Neptune vai gerar automaticamente representações de string de UUIDs para novas bordas e vértices.

Se você migrar dados do Neo4j para o Neptune exportando do Neo4j e depois importando em massa para o Neptune, poderá preservar os IDs do Neo4j. Os valores numéricos gerados pelo Neo4j podem atuar como IDs fornecidos pelo usuário ao importar para o Neptune, no qual são representados como strings em vez de valores numéricos.

No entanto, há circunstâncias em que convém promover uma propriedade de vértice para se tornar um ID de vértice. Assim como pesquisar um nó usando uma propriedade indexada é a maneira mais rápida de encontrar um nó no Neo4j, pesquisar um vértice por ID é a maneira mais rápida de encontrar um vértice no Neptune. Portanto, se você puder identificar uma propriedade de vértice adequada que contenha valores exclusivos, pense em substituir o \$1id do vértice pelo valor da propriedade indicada nos arquivos CSV de carregamento em massa. Se você fizer isso, também precisará reescrever todos os valores correspondentes de borda \$1from e \$1to nos arquivos CSV.

### Restrições do esquema ao migrar dados do Neo4j para o Neptune
<a name="migration-data-schema-constraints"></a>

No Neptune, a única restrição do esquema disponível é a exclusividade do ID de um nó ou uma borda. As aplicações que precisam aproveitar uma restrição de exclusividade são incentivadas a analisar essa abordagem para obter uma restrição de exclusividade por meio da especificação do ID do nó ou da borda. Se a aplicação usou várias colunas como restrição de exclusividade, o ID pode ser definido como uma combinação desses valores. Por exemplo, `id=123, code='SEA'` pode ser representado como `ID='123_SEA'` para obter uma restrição de exclusividade complexa.

### Otimização da direção da borda ao migrar dados do Neo4j para o Neptune
<a name="migration-data-edge-direction"></a>

Quando nós, bordas ou propriedades são adicionados ao Neptune, eles são automaticamente [indexados de três maneiras diferentes](feature-overview-storage-indexing.md), com um [quarto índice opcional](features-lab-mode.md#features-lab-mode-features-osgp-index). Devido à forma como o Neptune cria e [usa os índices](feature-overview-storage-indexing.md), as consultas que seguem as bordas de saída são mais eficientes do que as que usam bordas de entrada. Em termos do [modelo de armazenamento de dados de grafos](feature-overview-data-model.md) do Neptune, essas são pesquisas baseadas em assuntos que usam o índice SPOG.

Se, ao migrar o modelo de dados e consultas para o Neptune, você descobrir que as consultas mais importantes dependem de percorrer bordas de entrada onde há um alto grau de fanout, pense em alterar o modelo para que esses percursos sigam as bordas de saída, principalmente quando você não pode especificar quais rótulos de borda percorrer. Para fazer isso, inverta a direção das bordas relevantes e atualize os rótulos das bordas para refletir a semântica dessa mudança de direção. Por exemplo, você pode alterar:

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

Para fazer essa alteração em um [arquivo CSV de borda de carregamento em massa](bulk-load-tutorial-format.md), basta trocar os cabeçalhos das colunas `~from` e `~to` e atualizar os valores da coluna `~label`.

Como alternativa à inversão da direção das bordas, você pode habilitar um [quarto índice do Neptune, o índice OSGP](feature-overview-storage-indexing.md#feature-overview-storage-indexing-osgp), que torna o percurso das bordas de entrada ou as pesquisas baseadas em objetos muito mais eficiente. No entanto, habilitar esse quarto índice reduzirá as taxas de inserção e exigirá mais armazenamento.

### Otimização da filtragem ao migrar dados do Neo4j para o Neptune
<a name="migration-data-filtering"></a>

O Neptune é otimizado para funcionar melhor quando as propriedades são filtradas para a propriedade mais seletiva disponível. Quando vários filtros são usados, o conjunto de itens correspondentes é encontrado para cada um e, depois, a sobreposição de todos os conjuntos correspondentes é calculada. Quando possível, combinar várias propriedades em uma única propriedade minimiza o número de pesquisas de índice e diminui a latência de uma consulta.

Por exemplo, essa consulta usa duas pesquisas de índice e uma junção:

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

Essa consulta recupera as mesmas informações usando uma única pesquisa de índice:

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

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

O Neptune é compatível com [tipos de dados diferentes](bulk-load-tutorial-format-opencypher.md#bulk-load-tutorial-format-opencypher-data-types) dos do Neo4j.

**Mapeamentos de tipo de dados do Neo4j em tipos de dados compatíveis com o Neptune**
+ **Lógico**: `Boolean`

  Associe no Neptune a `Bool` ou a `Boolean`.
+ **Numérico**: `Number`

  Associe no Neptune ao mais restrito dos seguintes tipos do openCypher no Neptune que pode aceitar todos os valores da propriedade numérica em questão:

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

  Associe no Neptune a `String`.
+ **Ponto no tempo**:

  ```
    Date
    Time
    LocalTime
    DateTime
    LocalDateTime
  ```

  Associe no Neptune a `Date` como UTC, usando um dos seguintes formatos ISO-8601 aceitos pelo Neptune:

  ```
    yyyy-MM-dd
    yyyy-MM-ddTHH:mm
    yyyy-MM-ddTHH:mm:ss
    yyyy-MM-ddTHH:mm:ssZ
  ```
+ **Duração do tempo**: `Duration`

  Associe no Neptune a um valor numérico para aritmética de datas, se necessário.
+ **Espacial**: `Point`

  Associe no Neptune a valores numéricos de componentes, cada um dos quais se torna uma propriedade separada, ou expresse como um valor de string a ser interpretado pela aplicação cliente. Observe que a integração de [pesquisa de texto completo](full-text-search.md) do Neptune usando o OpenSearch permite indexar propriedades de geolocalização.

### Migrar propriedades de vários valores do Neo4j ao Neptune
<a name="migration-data-cardinality"></a>

O Neo4j permite que [listas homogêneas de tipos simples](https://neo4j.com/docs/cypher-manual/current/values-and-types/) sejam armazenadas como propriedades dos nós e das bordas. Essas listas podem conter valores duplicados.

O Neptune, no entanto, permite apenas [cardinalidade definida ou única](access-graph-gremlin-differences.md#feature-gremlin-differences-vertex-property-cardinality) para propriedades de vértice e cardinalidade única para propriedades de borda em dados de grafos de propriedades. Como resultado, não há migração direta de propriedades da lista de nós do Neo4j que contenham valores duplicados para as propriedades dos vértices de Neptune nem das propriedades da lista de relacionamentos do Neo4j para as propriedades da borda do Neptune.

Algumas estratégias possíveis para migrar propriedades de nós de vários valores do Neo4j com valores duplicados para o Neptune são as seguintes:
+ Descarte os valores duplicados e converta a propriedade do nó do Neo4j de vários valores em uma propriedade de vértice do Neptune de cardinalidade definida. Observe que o conjunto do Neptune pode não refletir a ordem dos itens na propriedade de vários valores do Neo4j original.
+ Converta a propriedade de nó do Neo4j de vários valores em uma representação de string de uma lista formatada em JSON em uma propriedade de string de vértice do Neptune.
+ Extraia cada um dos valores de propriedade de vários valores em um vértice separado com uma propriedade de valor e conecte esses vértices ao vértice pai usando uma borda rotulada com o nome da propriedade.

Da mesma forma, estratégias possíveis para migrar propriedades de relacionamento de vários valores do Neo4j para o Neptune são as seguintes:
+ Converta a propriedade de relacionamento do Neo4j de vários valores em uma representação de string de uma lista formatada em JSON em uma propriedade de string de borda do Neptune.
+ Refatore o relacionamento do Neo4j em bordas do Neptune de entrada e de saída conectadas a um vértice intermediário. Extraia cada um dos valores de propriedade de vários valores em um vértice separado com uma propriedade de valor e conecte esses vértices a esse vértice intermediário usando uma borda rotulada com o nome da propriedade.

Observe que uma representação de string de uma lista formatada em JSON é opaca para a linguagem de consulta openCypher, embora o openCypher inclua um predicado `CONTAINS` que permite pesquisas simples dentro de valores de string.

## Exportar dados do Neo4j ao migrar para o Neptune
<a name="migration-data-exporting"></a>

Ao exportar dados do Neo4j, use os procedimentos APOC para exportar para [CSV](https://neo4j.com/labs/apoc/4.1/export/csv/) ou [GraphML](https://neo4j.com/labs/apoc/4.1/export/graphml/). Embora seja possível exportar para outros formatos, existem [ferramentas de código aberto](https://github.com/awslabs/amazon-neptune-tools/tree/master/neo4j-to-neptune) para converter dados CSV exportados do Neo4j no formato de carregamento em massa do Neptune e também [ferramentas de código aberto](https://github.com/awslabs/amazon-neptune-tools/tree/master/graphml2csv) para converter dados do GraphML exportados do Neo4j para o formato de carregamento em massa do Neptune.

Também é possível exportar dados diretamente para o Amazon S3 usando os vários procedimentos APOC. A exportação para um bucket do Amazon S3 está desabilitada por padrão, mas pode ser habilitada usando os procedimentos destacados em [Exporting to Amazon S3](https://neo4j.com/labs/apoc/4.3/export/csv/#export-csv-s3-export) na documentação do APOC no Neo4j.

## Importar dados do Neo4j ao migrar para o Neptune
<a name="migration-data-importing"></a>

É possível importar dados para o Neptune usando o [carregador em massa do Neptune](bulk-load.md) ou usando a lógica da aplicação em uma linguagem de consulta compatível, como [openCypher](access-graph-opencypher.md).

O carregador em massa do Neptune é a abordagem preferencial para importar grandes quantidades de dados, pois oferece desempenho de importação otimizado caso você siga as [práticas recomendadas](bulk-load-optimize.md). O carregador em massa é compatível com [dois formatos CSV diferentes](bulk-load-tutorial-format.md), para os quais os dados exportados do Neo4j podem ser convertidos usando os utilitários de código aberto mencionados acima na seção [Exportar dados](#migration-data-exporting).

Você também pode usar o openCypher para importar dados com lógica personalizada para análise, transformação e importação. É possível enviar as consultas do openCypher por meio do [endpoint HTTPS](access-graph-opencypher-queries.md) (o que é recomendado) ou usando o [driver bolt](access-graph-opencypher-bolt.md).

# Migração de aplicações do Neo4j para o Neptune
<a name="migration-app-migration"></a>

Depois de migrar os dados do Neo4j para o Neptune, a próxima etapa é migrar a aplicação em si. Assim como acontece com os dados, há várias abordagens para migrar a aplicação com base nas ferramentas utilizadas, nos requisitos, nas diferenças de arquitetura, etc. Nesse processo, em geral, é necessário pensar nos fatores descritos abaixo.

## Migrar conexões ao transferir dados do Neo4j para o Neptune
<a name="migration-app-connections"></a>

Se, no momento, você não usa os drivers Bolt ou gostaria de usar uma alternativa, pode se conectar ao [endpoint HTTPS](access-graph-opencypher-queries.md), que concede acesso total aos dados exibidos. 

Se você tiver uma aplicação que use o [protocolo Bolt](access-graph-opencypher-bolt.md), poderá migrar essas conexões com o Neptune e permitir que as aplicações se conectem usando os mesmos drivers utilizados no Neo4j. Para se conectar ao Neptune, talvez seja necessário fazer uma ou mais das seguintes alterações na aplicação:
+ O URL e a porta precisarão ser atualizados para usar os endpoints e a porta do cluster (o padrão é 8182).
+ O Neptune exige que todas as conexões usem SSL, então é necessário especificar para cada conexão que ela está criptografada.
+ O Neptune gerencia a autenticação por meio da atribuição de [políticas e perfis do IAM](iam-auth.md). As políticas e os perfis do IAM oferecem um nível extremamente flexível de gerenciamento de usuários na aplicação, por isso é importante ler e entender as informações na [Visão geral do IAM](iam-auth.md) antes de configurar o cluster.
+ As conexões de parafusos se comportam de maneira diferente de várias maneiras no Neptune e no Neo4j, conforme explicado em [Comportamento da conexão do Bolt no Neptune](access-graph-opencypher-bolt.md#access-graph-opencypher-bolt-connections).
+ É possível encontrar mais informações e sugestões em [Práticas recomendadas para o Neptune ao usar openCypher e Bolt](best-practices-opencypher.md).

Há exemplos de código de linguagens comumente usadas, como Java, Python, .NET e NodeJS, e de cenários de conexão, como o uso da autenticação do IAM, em [Usar o protocolo Bolt para fazer consultas do openCypher ao Neptune](access-graph-opencypher-bolt.md).

## Direcionar consultas para instâncias de cluster ao migrar do Neo4j para o Neptune
<a name="migration-app-routing"></a>

As aplicações cliente do Neo4j usam um [driver de roteamento](https://neo4j.com/docs/driver-manual/1.7/client-applications/#routing_drivers_bolt_routing) e especificam um [modo de acesso](https://neo4j.com/docs/driver-manual/1.7/sessions-transactions/#driver-transactions-access-mode) para direcionar solicitações de leitura e gravação para um servidor apropriado em um cluster causal.

Ao migrar uma aplicação cliente para o Neptune, use os [endpoints do Neptune](feature-overview-endpoints.md) para direcionar consultas com eficiência para uma instância apropriada no cluster:
+ Todas as conexões com o Neptune devem usar `bolt://` em vez de `bolt+routing://` `neo4j://` ou o URL.
+ O endpoint de cluster conecta-se à instância principal atual do cluster. Use o endpoint de cluster para direcionar solicitações de gravação para a principal.
+ O endpoint de leitor [distribui conexões](best-practices-general-basic.md#best-practices-general-loadbalance) entre instâncias de réplica de leitura no cluster. Se você tiver um cluster de instância única sem instâncias de réplica de leitura, o endpoint de leitor se conectará à instância principal, que é compatível com operações de gravação. Se o cluster contiver uma ou mais instâncias de réplica de leitura, o envio de uma solicitação de gravação para o endpoint de leitor gerará uma exceção.
+ Cada instância no cluster também pode ter o próprio endpoint de instância. Use um endpoint de instância se a aplicação cliente precisar enviar uma solicitação a uma instância específica no cluster.

Para obter mais informações, consulte [Considerações sobre endpoint do Neptune](feature-overview-endpoints.md#feature-overview-endpoint-considerations).

## Consistência de dados no Neptune
<a name="migration-app-consistency"></a>

Ao usar clusters causais do Neo4j, as réplicas de leitura acabam sendo consistentes com os servidores centrais, mas as aplicações cliente podem garantir a consistência causal usando o [encadeamento causal](https://neo4j.com/docs/driver-manual/1.7/sessions-transactions/#driver-transactions-causal-chaining). O encadeamento causal envolve a transmissão de marcadores entre transações, o que permite que uma aplicação cliente grave em um servidor central e depois leia a própria gravação em uma réplica de leitura.

No Neptune, as instâncias de réplica de leitura acabam sendo consistentes com o gravador, com um atraso na réplica geralmente inferior a cem milissegundos. No entanto, até que uma alteração seja replicada, as atualizações nas bordas e nos vértices existentes e as adições de novas bordas e vértices não ficam visíveis em uma instância de réplica. Portanto, se a aplicação precisar de consistência imediata no Neptune lendo cada gravação, use o endpoint de cluster para a operação de leitura após gravação. Esse é o único momento de usar o endpoint de cluster para operações de leitura. Em todas as outras circunstâncias, use o endpoint de leitor para leituras.

## Migrar consultas do Neo4j para o Neptune
<a name="migration-app-queries"></a>

Embora o [suporte para openCypher](https://aws.amazon.com/blogs/database/announcing-the-general-availability-of-opencypher-support-for-amazon-neptune/) reduza drasticamente a quantidade de trabalho necessária para migrar consultas do Neo4j, ainda há algumas diferenças a serem avaliadas durante a migração:
+ Conforme abordado em [Otimizações do modelo de dados](migration-data-migration.md#migration-data-model-optimization) acima, pode haver modificações no modelo de dados que você precise fazer para criar um modelo de dados de grafos otimizado para o Neptune o que, por sua vez, exigirá alterações nas consultas e nos testes.
+ O Neo4j oferece uma série de extensões de linguagem específicas do Cypher que não estão incluídas na especificação do openCypher implementada pelo Neptune. Dependendo do caso de uso e do atributo utilizado, pode haver soluções alternativas na linguagem openCypher, no uso da linguagem Gremlin ou por meio de outros mecanismos, conforme descrito em [Reformular consultas do Cypher para serem executadas no openCypher no Neptune](migration-opencypher-rewrites.md).
+ As aplicações geralmente usam outros componentes de middleware para interagir com o banco de dados, em vez dos próprios drivers do Bolt. Confira [Compatibilidade do Neptune com o Neo4j](migration-compatibility.md) para ver se as ferramentas ou o middleware que você está usando são compatíveis.
+ No caso de um failover, o driver do Bolt pode continuar se conectando à instância de gravador ou de leitor anterior porque o endpoint de cluster fornecido à conexão foi resolvido para um endereço IP. O tratamento adequado de erros na aplicação deve resolver isso, conforme descrito em [Criar uma conexão após o failover](best-practices-opencypher.md#best-practices-opencypher-renew-connection).
+ Quando as transações são canceladas devido a conflitos não resolvidos ou a tempos limite de espera de bloqueio, o Neptune responde com uma `ConcurrentModificationException`. Para obter mais informações, consulte [Códigos de erro do mecanismo](errors-engine-codes.md). Como melhor prática, os clientes sempre devem capturar e lidar com essas exceções.

  A `ConcurrentModificationException` ocorre ocasionalmente quando vários encadeamentos ou várias aplicações estão gravando no sistema simultaneamente. Devido aos [níveis de isolamento de transações](transactions-neptune.md#transactions-neptune-mutation), esses conflitos às vezes podem ser inevitáveis.
+ O Neptune é compatível com a execução de consultas do Gremlin e do openCypher nos mesmos dados. Isso significa que, em algumas situações, talvez seja necessário pensar no uso do Gremlin, com os recursos de consulta mais poderosos, para realizar algumas das funcionalidades das consultas.

Conforme abordado em [Provisionar infraestrutura](migration-provisioning-infrastructure.md) acima, cada aplicação deve passar por um exercício de dimensionamento correto para garantir que o número de instâncias, os tamanhos das instâncias e a topologia do cluster sejam otimizados para a workload específica da aplicação.

As considerações abordadas aqui para migrar a aplicação são as mais comuns, mas não se trata de uma lista completa. Cada aplicação é exclusiva. Em caso de mais dúvidas, entre em contato com o AWS Support ou entre em contato com a equipe de sua conta.

## Migrar atributos e ferramentas específicos do Neo4j
<a name="migration-app-neo4j-specific"></a>

O Neo4j tem uma série de atributos e complementos personalizados com funcionalidades nas quais a aplicação pode confiar. Ao avaliar a necessidade de migrar essa funcionalidade, geralmente é útil investigar se existe uma abordagem melhor na AWS para concretizar o mesmo objetivo. Considerando as [diferenças de arquitetura entre o Neo4j e o Neptune](migration-architectural-differences.md), muitas vezes é possível encontrar alternativas eficazes que utilizem outros serviços ou [integrações](integrations.md) da AWS.

Consulte [Compatibilidade do Neptune com o Neo4j](migration-compatibility.md) para obter uma lista de atributos específicos do Neo4j e soluções alternativas sugeridas.

# Compatibilidade do Neptune com o Neo4j
<a name="migration-compatibility"></a>

O Neo4j tem uma abordagem completa em que o carregamento e o ETL de dados, as consultas de aplicações, o armazenamento de dados e as operações de gerenciamento acontecem no mesmo conjunto de recursos computacionais, como instâncias do EC2. O Amazon Neptune é um banco de dados de grafos de especificações abertas concentrado em OLTP em que a arquitetura separa as operações e desconecta os recursos para que eles possam ser escalados dinamicamente.

Há uma série de atributos e ferramentas no Neo4j, incluindo ferramentas de terceiros, que não fazem parte da especificação do openCypher, são incompatíveis com o openCypher ou com a implementação do openCypher pelo Neptune. Veja alguns dos mais comuns listados.

## Atributos específicos do Neo4j não presentes no Neptune
<a name="migration-compatibility-features"></a>
+ **`LOAD CSV`**: o Neptune tem uma abordagem arquitetônica diferente do Neo4j para carregar dados. Para permitir uma melhor escalabilidade e otimização de custos, o Neptune implementa uma separação de preocupações em relação aos recursos e recomenda o uso de uma das [integrações de serviços da AWS](integrations.md), como AWS Glue para executar os processos de ETL necessários para preparar dados em um [formato](bulk-load-tutorial-format.md) compatível com o [carregador em massa do Neptune](bulk-load.md).

  Outra opção é fazer a mesma coisa usando o código da aplicação executado em recursos computacionais da AWS, como instâncias do Amazon EC2, funções do Lambda, Amazon Elastic Container Service, trabalhos AWS Batch, etc. O código pode usar o [endpoint HTTPS](access-graph-opencypher-queries.md) do Neptune ou o [endpoint do Bolt](access-graph-opencypher-bolt.md).
+ **Controle de acesso refinado**: o Neptune é compatível com o controle de acesso granular sobre ações de acesso a dados [usando chaves de condição do IAM](iam-data-access-policies.md). Controle de acesso refinado adicional pode ser implementado na camada de aplicação.
+ **Neo4j Fabric**: o Neptune é compatível com a federação de consultas em bancos de dados para workloads do RDF usando a palavra-chave [`SERVICE`](sparql-service.md) do SPARQL. Como no momento não há um padrão aberto nem uma especificação para federação de consultas para workloads de grafos de propriedades, essa funcionalidade precisaria ser implementada na camada da aplicação.
+ **Controle de acesso baseado em perfil (RBAC)**: o Neptune gerencia a autenticação por meio da atribuição de [políticas e perfis do IAM](iam-auth.md). As políticas e os perfis do IAM oferecem um nível extremamente flexível de gerenciamento de usuários em um aplicação, por isso é útil ler e entender as informações na [Visão geral do IAM](iam-auth.md) antes de configurar o cluster.

  
+ **Marcação**: os clusters do Neptune consistem em uma única instância de gravador e até 15 instâncias de réplica de leitura. Os dados gravados na instância de gravador são compatíveis com ACID e fornecem uma forte garantia de consistência nas leituras subsequentes. As réplicas de leitura usam o mesmo volume de armazenamento da instância de gravador e acabam sendo consistentes, em geral, em menos de 100 ms a partir do momento em que os dados são gravados. Se o caso de uso tiver uma necessidade imediata de garantir a consistência de leitura de novas gravações, essas leituras deverão ser direcionadas para o endpoint de cluster em vez do endpoint de leitor.
+ **Procedimentos APOC**: como os procedimentos APOC não estão incluídos na especificação do openCypher, o Neptune não oferece suporte direto para procedimentos externos. Em vez disso, o Neptune depende de [integrações com outros serviços da AWS](integrations.md) para obter uma funcionalidade semelhante ao usuário final de maneira escalável, segura e sólida. Às vezes, os procedimentos APOC podem ser regravados em openCypher ou em Gremlin, e alguns não são relevantes para as aplicações do Neptune.

  Em geral, os procedimentos APOC se enquadram nas categorias abaixo:
  + **[Importar](https://neo4j.com/labs/apoc/4.2/import/)**: o Neptune é compatível com a importação de dados com uma variedade de formatos usando linguagens de consulta, o [carregador em massa](bulk-load.md) do Neptune ou como destino do [AWS Database Migration Service](dms-neptune.md). As operações de ETL nos dados podem ser realizadas com AWS Glue e o pacote de código aberto [https://github.com/awslabs/amazon-neptune-tools/tree/master/neptune-python-utils](https://github.com/awslabs/amazon-neptune-tools/tree/master/neptune-python-utils).
  + **[Exportar](https://neo4j.com/labs/apoc/4.2/export/)**: o Neptune é compatível com a exportação de dados usando o utilitário [`neptune-export`](neptune-data-export.md), que é compatível com uma variedade de formatos e métodos de exportação comuns.
  + **[Integração de banco de dados](https://neo4j.com/labs/apoc/4.2/database-integration/)**: o Neptune é compatível com a integração com outros bancos de dados usando ferramentas ETL, como AWS Glue ou ferramentas de migração, como o [AWS Database Migration Service](dms-neptune.md).
  + **[Atualizações de grafos](https://neo4j.com/labs/apoc/4.2/graph-updates/)**: o Neptune é compatível com um rico conjunto de atributos para atualizar dados de grafos de propriedades por meio do suporte para as linguagens de consulta openCypher e Gremlin. Consulte [Reformulações do Cypher](migration-opencypher-rewrites.md) para obter exemplos de regravações de procedimentos usados com frequência.
  + **[Estruturas de dados](https://neo4j.com/labs/apoc/4.2/data-structures/)**: o Neptune é compatível com um rico conjunto de atributos para atualizar dados de grafos de propriedades por meio do suporte para as linguagens de consulta openCypher e Gremlin. Consulte [Reformulações do Cypher](migration-opencypher-rewrites.md) para obter exemplos de regravações de procedimentos usados com frequência.
  + **[Temporal (data e hora)](https://neo4j.com/labs/apoc/4.2/temporal/)**: o Neptune é compatível com um rico conjunto de atributos para atualizar dados de grafos de propriedades por meio do suporte para as linguagens de consulta openCypher e Gremlin. Consulte [Reformulações do Cypher](migration-opencypher-rewrites.md) para obter exemplos de regravações de procedimentos usados com frequência.
  + **[Matemático](https://neo4j.com/labs/apoc/4.2/mathematical/)**: o Neptune é compatível com um rico conjunto de atributos para atualizar dados de grafos de propriedades por meio do suporte para as linguagens de consulta openCypher e Gremlin. Consulte [Reformulações do Cypher](migration-opencypher-rewrites.md) para obter exemplos de regravações de procedimentos usados com frequência.
  + **[Consultas de grafos avançadas](https://neo4j.com/labs/apoc/4.2/graph-querying/)**: o Neptune é compatível com um rico conjunto de atributos para atualizar dados de grafos de propriedades por meio do suporte para as linguagens de consulta openCypher e Gremlin. Consulte [Reformulações do Cypher](migration-opencypher-rewrites.md) para obter exemplos de regravações de procedimentos usados com frequência.
  + **[Comparação de grafos](https://neo4j.com/labs/apoc/4.2/comparing-graphs/)**: o Neptune é compatível com um rico conjunto de atributos para atualizar dados de grafos de propriedades por meio do suporte para as linguagens de consulta openCypher e Gremlin. Consulte [Reformulações do Cypher](migration-opencypher-rewrites.md) para obter exemplos de regravações de procedimentos usados com frequência.
  + **[Execução do Cypher](https://neo4j.com/labs/apoc/4.2/cypher-execution/)**: o Neptune é compatível com um rico conjunto de atributos para atualizar dados de grafos de propriedades por meio do suporte para as linguagens de consulta openCypher e Gremlin. Consulte [Reformulações do Cypher](migration-opencypher-rewrites.md) para obter exemplos de regravações de procedimentos usados com frequência.
+ **Procedimentos personalizados**: o Neptune não é compatível com procedimentos personalizados criados por usuários. Essa funcionalidade teria que ser implementada na camada da aplicação.
+ **Geoespacial**: embora o Neptune não ofereça suporte nativo para atributos geoespaciais, uma funcionalidade semelhante pode ser obtida por meio da integração com outros serviços da AWS, conforme mostrado nesta postagem no 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/) de Ross Gabay e Abhilash Vinod (1.º de fevereiro de 2022).
+ **Ciência de dados de grafos**: o Neptune oferece suporte à análise de grafos por meio do [Neptune Analytics](https://docs.aws.amazon.com/neptune-analytics/latest/userguide/what-is-neptune-analytics.html), um mecanismo otimizado para memória compatível com uma biblioteca de algoritmos analíticos de grafos.

  O Neptune também oferece integração com o [SDK do AWS Pandas](https://github.com/amazon-archives/fully-automated-neo4j-to-neptune) e [vários exemplos de bloco de anotações](https://github.com/aws/graph-notebook/tree/main/src/graph_notebook/notebooks/05-Data-Science) que mostram como aproveitar essa integração em ambientes Python para realizar análises em dados de grafos.

  
+ **Restrições do esquema**: no Neptune, a única restrição do esquema disponível é a exclusividade do ID de um nó ou uma borda. Não há nenhum atributo para especificar restrições adicionais do esquema nem qualquer restrição adicional de exclusividade ou valor em um elemento no grafo. Os valores de ID no Neptune são strings e podem ser definidos usando Gremlin, da seguinte forma:

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

  As aplicações que precisam utilizar o ID como restrição de exclusividade são incentivadas a tentar essa abordagem para obter uma restrição de exclusividade. Se a aplicação usou várias colunas como restrição de exclusividade, o ID pode ser definido como uma combinação desses valores. Por exemplo, `id=123, code='SEA'` pode ser representado como `ID='123_SEA'` para obter uma restrição de exclusividade complexa.
+ **Multilocação**: o Neptune é compatível apenas com um único grafo por cluster. Para criar um sistema multilocatário usando o Neptune, use vários clusters ou particione logicamente os locatários em um único grafo e use a lógica do lado da aplicação para impor a separação. Por exemplo, adicione uma propriedade `tenantId` e inclua-a em cada consulta, da seguinte forma:

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

  [O Neptune Serverless](neptune-serverless.md) torna relativamente fácil implementar a multilocação usando vários clusters de banco de dados, sendo cada um escalado de forma independente e automática conforme necessário.

## Suporte do Neptune para ferramentas do Neo4j
<a name="migration-compatibility-tools"></a>

O Neptune oferece as seguintes alternativas às ferramentas do Neo4j:
+ **[Neo4j Browser](https://neo4j.com/docs/operations-manual/current/installation/neo4j-browser/)**: o Neptune fornece [blocos de anotações de grafos](graph-notebooks.md) de código aberto que fornecem um IDE enfocado no desenvolvedor para executar consultas e visualizar os resultados.
+ **[Neo4j Bloom](https://neo4j.com/product/bloom/)**: o Neptune é compatível com visualizações de grafos avançadas usando [soluções de visualização de terceiros](visualization-tools.md), como Graph-explorer, Tom Sawyer, Cambridge Intelligence, Graphistry, metaphacts e G.V().
+ **[GraphQL](https://graphql.org/)**: no momento, o Neptune é compatível com o GraphQL por meio de integrações AWS AppSync personalizadas. Consulte a postagem no 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/) e o exemplo de projeto, [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/)**: o Neptune oferece suporte nativo ao modelo de dados do RDF, portanto, os clientes que desejam executar workloads do RDF são aconselhados a usar o suporte ao modelo do RDF do Neptune.
+ **[Arrows.app](https://arrows.app/)**: o Cypher criado ao exportar o modelo usando o comando export é compatível com o Neptune.
+ **[Linkurious Ogma](https://doc.linkurious.com/ogma/latest/)**: um exemplo de integração com o Linkurious Ogma está [disponível aqui](https://github.com/aws-samples/amazon-neptune-samples/tree/master/gremlin/ogma-neptune).
+ **[Spring Data Neo4j](https://spring.io/projects/spring-data-neo4j)**: no momento, não é compatível com o Neptune.
+ **[Conector Spark do Neo4j](https://neo4j.com/docs/spark/current/)**: o conector Spark do Neo4j pode ser usado em um trabalho do Spark para se conectar ao Neptune usando o openCypher. Veja alguns exemplos de código e configuração da aplicação:

  **Código de exemplo:**

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

  **Configuração da aplicação:**

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

### Atributos e ferramentas do Neo4j não listados aqui
<a name="migration-compatibility-tools-unlisted"></a>

Se você estiver usando uma ferramenta ou um atributo não listado aqui, não temos certeza da compatibilidade com o Neptune ou com outros serviços da AWS contidos nele. Em caso de mais dúvidas, entre em contato com o AWS Support ou entre em contato com a equipe de sua conta.

# Reformular consultas do Cypher para serem executadas no openCypher no Neptune
<a name="migration-opencypher-rewrites"></a>

O openCypher é uma linguagem de consulta declarativa para grafos de propriedades originalmente desenvolvida pela Neo4j, que passou a ser de código aberto em 2015, e contribuiu para o [projeto openCypher](https://www.opencypher.org/) sob uma licença de código aberto Apache 2. Na AWS, acreditamos que o código aberto é bom para todos e estamos comprometidos em trazer o valor do código aberto aos nossos clientes e a excelência operacional das AWS comunidades de código aberto.

OpenCypher a sintaxe está documentada na [Cypher Query Language Reference, versão 9](https://s3.amazonaws.com/artifacts.opencypher.org/openCypher9.pdf).

Como o openCypher contém um subconjunto da sintaxe e atributos da linguagem de consulta Cypher, alguns cenários de migração exigem a reformulação de consultas em formas compatíveis com o openCypher ou a análise de métodos alternativos para obter a funcionalidade desejada.

Esta seção contém recomendações para lidar com diferenças comuns, mas elas não são completas. É necessário testar as aplicações usando essas reformulações minuciosamente a fim de garantir que os resultados sejam os esperados.

## Reformular funções de predicado `None`, `All` e `Any`
<a name="migration-opencypher-rewrites-none-all-any"></a>

Essas funções não fazem parte da especificação do openCypher. É possível obter resultados comparáveis no openCypher usando a compreensão de lista.

Por exemplo, encontre todos os caminhos que vão do nó `Start` ao `End` , mas nenhuma jornada pode passar por um nó com a propriedade de classe `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
```

A compreensão de lista pode alcançar esses resultados da seguinte forma:

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

## Reformulando a função `reduce()` do Cypher em openCypher.
<a name="migration-opencypher-rewrites-reduce"></a>

A função `reduce()` não faz parte da especificação do openCypher. Geralmente é usada para criar uma agregação de dados a partir de elementos em uma lista. Em muitos casos, é possível usar uma combinação de compreensão de lista e a cláusula `UNWIND` para obter resultados semelhantes.

Por exemplo, a consulta do Cypher a seguir encontra todos os aeroportos em caminhos com uma a três paradas entre Anchorage (ANC) e Austin (AUS) e exibe a distância total de cada caminho:

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

Você pode reformular a mesma consulta em openCypher para Neptune da seguinte forma:

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

## Reformulando a cláusula FOREACH do Cypher em openCypher.
<a name="migration-opencypher-rewrites-foreach"></a>

A cláusula FOREACH não faz parte da especificação do openCypher. Em geral, é usada para atualizar dados no meio de uma consulta, geralmente de agregações ou elementos em um caminho.

Como exemplo de caminho, encontre todos os aeroportos em um caminho com no máximo duas paradas entre Anchorage (ANC) e Austin (AUS) e defina uma propriedade visitada em cada um deles:

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

Outro exemplo é:

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

## Reformulando procedimentos APOC do Neo4j no Neptune.
<a name="migration-opencypher-rewrites-apoc"></a>

Os exemplos abaixo usam o openCypher para substituir alguns dos [procedimentos APOC](https://neo4j.com/blog/intro-user-defined-procedures-apoc/) mais usados. Esses exemplos são apenas para referência e têm como objetivo fornecer algumas sugestões sobre como lidar com cenários comuns. Na prática, cada aplicação é diferente e você precisará criar suas próprias estratégias para fornecer todas as funcionalidades de que precisa.

### Procedimentos de reformulação de `apoc.export`
<a name="migration-opencypher-rewrites-apoc-export"></a>

O Neptune fornece uma variedade de opções para exportações completas com base em grafos e consultas em vários formatos de saída, como CSV e JSON, usando o utilitário [neptune-export](https://github.com/aws/neptune-export) (consulte [Exportar dados de um cluster de banco de dados do Neptune](neptune-data-export.md)).

### Procedimentos de reformulação de `apoc.schema`
<a name="migration-opencypher-rewrites-apoc-schema"></a>

O Neptune não tem esquemas, índices nem restrições explicitamente definidos, portanto, muitos procedimentos `apoc.schema` não são mais necessários. Veja estes exemplos:
+ `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`

O openCypher no Neptune é compatível com a recuperação de valores semelhantes aos dos procedimentos, conforme mostrado abaixo, mas pode ter problemas de desempenho em grafos maiores, pois isso requer a verificação de uma grande parte do grafo para exibir a resposta.

```
# 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 aos procedimentos `apoc.do`
<a name="migration-opencypher-rewrites-apoc-do"></a>

Esses procedimentos são usados para fornecer uma execução condicional de consultas que seja fácil de implementar usando outras cláusulas do openCypher. No Neptune, existem pelo menos duas maneiras de obter um comportamento semelhante:
+ Uma delas é combinar os recursos de compreensão de listas do openCypher com a cláusula `UNWIND`.
+ Outra forma é usar as etapas choose() e coalesce() no Gremlin.

Exemplos dessas abordagens são mostrados abaixo.

#### Alternativas para 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 para 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 às propriedades baseadas em listas
<a name="migration-opencypher-rewrites-lists"></a>

No momento, o Neptune não aceita o armazenamento de propriedades baseadas em listas. No entanto, resultados semelhantes podem ser obtidos armazenando os valores da lista como uma string separada por vírgula e, depois, usando as funções `join()` e `split()` para construir e desconstruir a propriedade da lista.

Por exemplo, se quisermos salvar uma lista de tags como uma propriedade, poderemos usar o exemplo de reformulação, que mostra como recuperar uma propriedade separada por vírgula e, depois, usar as funções `split()` e `join()` com a compreensão de lista para obter resultados comparáveis:

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

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

 As subconsultas `CALL` do Neptune não oferecem suporte à sintaxe `CALL (friend) { ... }` para importar variáveis para o escopo da subconsulta (`friend`, neste exemplo). Use a cláusula `WITH` dentro da subconsulta para o mesmo, por exemplo, `CALL { WITH friend ... }`. 

 Atualmente, não há suporte para subconsultas `CALL` opcionais. 

## Outras diferenças entre o openCypher e o Cypher do Neptune
<a name="opencypher-compliance-other-differences"></a>
+ O Neptune só suporta conexões TCP para o protocolo Bolt. WebSocketsconexões para Bolt não são suportadas.
+ O openCypher do Neptune remove o espaço em branco conforme definido pelo Unicode nas funções `trim()`, `ltrim()` e `rtrim()`.
+ No openCypher do Neptune, `tostring(`duplo`)` não muda automaticamente para a notação E para valores grandes do duplo.

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

O Neptune oferece várias ferramentas e recursos que podem auxiliar no processo de migração.

**Ferramentas para ajudar a migrar do Neo4j para o Neptune**
+ O 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) — Um utilitário de linha de comando para migrar dados do Neo4j para o Neptune. Essa ferramenta inclui a capacidade de:
  + Exporte os dados de um gráfico Neo4j configurado corretamente.
  + Converta esses dados no formato Neptune.
  + Carregue esses dados em massa no Neptune.
  + Execute algumas conversões básicas de dados durante a conversão para o formato Netuno, como renomear rótulos de vértices ou bordas e gerar elementos.
  + Gere propriedades para nós e bordas usando modelos (por exemplo, crie um `~id` valor usando um modelo, como `Person_{personid}` para situações em que você precisa criar o identificador exclusivo para um elemento).
+ [Verificador de compatibilidade de consultas OpenCypher](https://github.com/awslabs/amazon-neptune-tools/tree/master/opencypher-compatability-checker) — Essa ferramenta recebe uma entrada de consultas do OpenCypher e irá:
  + Verifique a compatibilidade com a versão selecionada do Neptune.
  + Identifique funções e cláusulas específicas não suportadas com suas posições.
  + Sugira substituições, se disponíveis.
  + Forneça descrições de erros de quaisquer outros erros de sintaxe.