

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# Neo4j から Neptune へのデータ移行
<a name="migration-data-migration"></a>

Neo4j から Amazon Neptune への移行を実行する場合、データの移行はプロセスの主要なステップです。データを移行するには複数の方法があります。適切な方法は、アプリケーションのニーズ、データサイズ、必要な移行の種類によって決まります。ただし、これらの移行の多くでは、すべて同じ考慮事項を評価する必要があります。そのいくつかを以下に述べます。

**注記**  
オフラインデータ移行の実行例の順を追った詳しい説明については、[AWS データベースブログ](https://aws.amazon.com/blogs/?awsf.blog-master-category=category%23database)の「[完全自動化ユーティリティによる Neo4j グラフデータベースから Amazon Neptune への移行](https://aws.amazon.com/blogs/database/migrating-a-neo4j-graph-database-to-amazon-neptune-with-a-fully-automated-utility/)」を参照してください。

## Neo4j から Neptune へのデータ移行の評価
<a name="migration-data-assessment"></a>

データ移行を評価する際の最初のステップは、データの移行方法を決定することです。オプションは、移行するアプリケーションのアーキテクチャ、データサイズ、移行中の可用性ニーズによって異なります。一般に、移行はオンラインとオフラインの 2 つのカテゴリのいずれかに分類されます。

オフライン移行は、移行中にアプリケーションが読み取りまたは書き込みトラフィックを受け付けないため、簡単に実行できる傾向があります。アプリケーションがトラフィックを受け付けなくなったら、データのエクスポート、最適化、インポートを行うことができ、アプリケーションを再度有効にする前にアプリケーションをテストできます。

オンライン移行では、データの移行中もアプリケーションが読み取り/書き込みトラフィックを受け入れる必要があるため、より複雑です。各オンライン移行の正確なニーズはそれぞれ異なる場合がありますが、一般的なアーキテクチャは以下のようになります。
+ [Neo4j ストリームを Kafka クラスターのソースとして](https://neo4j.com/labs/kafka/4.0/producer/)設定することにより、データベースニーズに対する継続的な変更のフィードを Neo4j で有効にする必要があります。
+ これが完了すると、[Neptune への移行時に Neo4j からデータをエクスポートする](#migration-data-exporting) に記載されている指示に従って、実行中のシステムをエクスポートできます。この時間は後で Kafka のトピックと関連付けられます。
+ エクスポートされたデータは、[Neptune への移行時に Neo4j からデータをインポートする](#migration-data-importing) の説明に従って Neptune にインポートされます。
+ Kafka ストリームから変更されたデータは、「[Amazon Kinesis Data Streams から Amazon Neptune への書き込み](https://github.com/aws-samples/amazon-neptune-samples/tree/master/gremlin/stream-2-neptune)」で説明されているものと同様のアーキテクチャを使用して、Neptune クラスターにコピーできます。変更の複製を並行して実行し、新しいアプリケーションアーキテクチャとパフォーマンスを検証できることに注意してください。
+ データ移行が検証されたら、アプリケーショントラフィックを Neptune クラスターにリダイレクトし、Neo4j インスタンスを廃止できます。

## Neo4j から Neptune への移行のためのデータモデルの最適化
<a name="migration-data-model-optimization"></a>

Neptune と Neo4j はどちらもラベル付きプロパティグラフ (LPG) をサポートしています。ただし、Neptune には、パフォーマンスを最適化するために活用できるアーキテクチャとデータモデルの違いがいくつかあります。

### ノード ID とエッジ ID の最適化
<a name="migration-data-node-edge-id-optimization"></a>

Neo4j は数字の長い ID を自動的に生成します。Cypher を使用して ID でノードを参照できますが、インデックス付きのプロパティでノードを検索するほうが好ましいので、一般的にはお勧めできません。

Neptune では、[頂点とエッジに独自の文字列ベースの ID を指定できます](access-graph-gremlin-differences.md#feature-gremlin-differences-user-supplied-ids)。独自の ID を指定しなかった場合、Neptune は新しいエッジと頂点の UUID の文字列表現を自動的に生成します。

Neo4j からエクスポートしてから Neptune に一括インポートすることによって Neo4j から Neptune にデータを移行すると、Neo4j の ID を保持できます。Neo4j によって生成された数値は、Neptune にインポートする際にユーザー指定の ID として機能し、数値ではなく文字列として表されます。

ただし、頂点プロパティを頂点 ID に昇格させたい場合もあります。インデックス付きプロパティを使用してノードを検索するのが Neo4j でノードを見つける最も速い方法であるように、ID で頂点を検索するのが Neptune で頂点を見つける最も速い方法です。したがって、一意の値を含む適切な頂点プロパティを特定できる場合は、一括読み込み CSV ファイルの vertex\$1id を指定されたプロパティ値に置き換えることを検討してください。その場合は、CSV ファイル内の対応する \$1from および \$1to エッジ値もすべて書き換える必要があります。

### Neo4j から Neptune にデータを移行する際のスキーマの制約
<a name="migration-data-schema-constraints"></a>

Neptune 内で利用できる唯一のスキーマ制約は、ノードまたはエッジの ID の一意性です。一意性制約を利用する必要があるアプリケーションでは、ノードまたはエッジ ID を指定して一意性制約を実現するこのアプローチを検討することをお勧めします。アプリケーションが一意性制約として複数の列を使用している場合は、ID をこれらの値の組み合わせに設定できます。例えば、`id=123, code='SEA'` を `ID='123_SEA'` として表して、複雑な一意性制約を実現できます。

### Neo4j から Neptune へのデータ移行時のエッジ方向の最適化
<a name="migration-data-edge-direction"></a>

ノード、エッジ、またはプロパティが Neptune に追加されると、[3 つの異なる方法で自動的にインデックスが付けられ](feature-overview-storage-indexing.md)、[オプションで 4 番目のインデックス](features-lab-mode.md#features-lab-mode-features-osgp-index)が作成されます。Neptune が[インデックスを構築して使用](feature-overview-storage-indexing.md)する方法により、出力エッジに従うクエリの方が、入力エッジを使用するクエリよりも効率的です。Neptune の[グラフデータストレージモデル](feature-overview-data-model.md)では、これらは SPOG インデックスを使用するサブジェクトベースの検索です。

データモデルとクエリを Neptune に移行する際、最も重要なクエリが、ファンアウトの度合いが高い入力エッジのトラバースに依存していることがわかった場合は、特にトラバースするエッジラベルを指定できないときには、これらのトラバーサルが代わりに出力エッジに従うようにモデルを変更することを検討してください。そのためには、関連するエッジの方向を逆にして、この方向変更のセマンティクスを反映するようにエッジラベルを更新します。例えば、次のように変更します。

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

この変更を[一括読み込みエッジ CSV ファイル](bulk-load-tutorial-format.md)で行うには、`~from` と `~to` の列見出しを入れ替えて、`~label` 列の値を更新するだけです。

エッジ方向を逆にする代わりに、[4 番目の Neptune インデックスである OSGP インデックス](feature-overview-storage-indexing.md#feature-overview-storage-indexing-osgp)を有効にできます。これにより、入力エッジのトラバースやオブジェクトベースの検索がより効率的になります。ただし、この 4 番目のインデックスを有効にすると、挿入速度が低下し、より多くのストレージが必要になります。

### Neo4j から Neptune へのデータ移行時のフィルタリングの最適化
<a name="migration-data-filtering"></a>

Neptune は、プロパティが利用可能な最も選択的なプロパティにフィルタリングされたときに最もよく機能するように最適化されています。複数のフィルターを使用すると、それぞれに一致する項目のセットが見つかり、一致するすべてのセットのオーバーラップが計算されます。可能であれば、複数のプロパティを 1 つのプロパティにまとめることで、インデックス検索の回数を最小限に抑え、クエリのレイテンシーを短縮できます。

例えば、次のクエリでは 2 つのインデックス検索と 1 つの結合を使用します。

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

このクエリは 1 回のインデックス検索で同じ情報を取得します。

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

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

Neptune は Neo4j とは[異なるデータ型](bulk-load-tutorial-format-opencypher.md#bulk-load-tutorial-format-opencypher-data-types)をサポートしています。

**NNeptune がサポートするデータ型への Neo4j データ型マッピング**
+ **論理**: `Boolean`

  これを Neptune で `Bool` または `Boolean` にマッピングします。
+ **数値**: `Number`

  これを Neptune で次の Neptune openCypher 型のうち、問題の数値プロパティのすべての値をサポートできる最も狭いものにマッピングします。

  ```
    Byte
    Short
    Integer
    Long
    Float
    Double
  ```
+ **テキスト**: `String`

  これを Neptune で `String` にマッピングします。
+ **ポイントインタイム**:

  ```
    Date
    Time
    LocalTime
    DateTime
    LocalDateTime
  ```

  Neptune がサポートする次のいずれかの ISO-8601 形式を使用して、これらを Neptune で UTC として `Date` にマッピングします。

  ```
    yyyy-MM-dd
    yyyy-MM-ddTHH:mm
    yyyy-MM-ddTHH:mm:ss
    yyyy-MM-ddTHH:mm:ssZ
  ```
+ **期間**: `Duration`

  必要に応じて、これを Neptune で数値にマッピングして日付計算を行います。
+ **空間**: `Point`

  これを Neptune でコンポーネントの数値にマッピングします。各数値は個別のプロパティになるか、クライアントアプリケーションによって解釈される文字列値として表現されます。OpenSearch を使用した Neptune の[フルテキスト検索](full-text-search.md)統合により、位置情報プロパティをインデックス化できることに注意してください。

### Neo4j から Neptune への多値プロパティの移行
<a name="migration-data-cardinality"></a>

Neo4j では、[単純型の同種リスト](https://neo4j.com/docs/cypher-manual/current/values-and-types/)をノードとエッジの両方のプロパティとして保存できます。これらのリストには重複する値が含まれる場合があります。

ただし、Neptune では、頂点プロパティとしては[設定された、または単一のカーディナリティ](access-graph-gremlin-differences.md#feature-gremlin-differences-vertex-property-cardinality)のみが許され、プロパティグラフデータのエッジプロパティとしては単一カーディナリティのみが許されます。その結果、重複する値を含む Neo4j ノードリストプロパティをNeptune 頂点プロパティに直接移行したり、Neo4j リレーションシップリストプロパティを Neptune エッジプロパティに直接移行したりすることはできません。

重複する値を持つ Neo4j 多値ノードプロパティを Neptune に移行するためのいくつかの可能な戦略は次のとおりです。
+ 重複する値を破棄し、多値の Neo4j ノードプロパティを設定されたカーディナリティの Neptune 頂点プロパティに変換します。その場合、Neptune セットは元の Neo4j 多値プロパティの項目の順序を反映しない場合があることに注意してください。
+ 多値 Neo4j ノードプロパティを、Neptune 頂点文字列プロパティ内の JSON 形式リストの文字列表現に変換します。
+ 多値プロパティ値のそれぞれを値プロパティを持つ個別の頂点に抽出し、プロパティ名のラベルが付いたエッジを使用して、それらの頂点を親頂点に接続します。

同様に、Neo4j 多値リレーションシッププロパティを Neptune に移行するためのいくつかの可能な戦略は次のとおりです。
+ 多値 Neo4j リレーションシッププロパティを、JSON 形式リストの文字列表現に変換して、Neptune エッジ文字列プロパティとして保存します。
+ Neo4j のリレーションシップを、中間頂点に接続された Neptune 入力エッジと出力エッジにリファクタリングします。多値リレーションシッププロパティ値のそれぞれを値プロパティを持つ個別の頂点に抽出し、プロパティ名のラベルが付いたエッジを使用して、それらの頂点をこの中間頂点に接続します。

openCypher には文字列値の中を簡単に検索できる `CONTAINS` 述語が含まれていますが、JSON 形式のリストの文字列表現は openCypher クエリ言語では不透明であることに注意してください。

## Neptune への移行時に Neo4j からデータをエクスポートする
<a name="migration-data-exporting"></a>

Neo4j からデータをエクスポートするときには、APOC プロシージャを使用して [CSV](https://neo4j.com/labs/apoc/4.1/export/csv/) または [GraphML](https://neo4j.com/labs/apoc/4.1/export/graphml/) にエクスポートしてください。他の形式にエクスポートすることも可能ですが、Neo4j からエクスポートされた CSV データを Neptune のバルクロード形式に変換するための[オープンソースツール](https://github.com/awslabs/amazon-neptune-tools/tree/master/neo4j-to-neptune)や、Neo4j からエクスポートされた GraphML データを Neptune バルクロード形式に変換するための[オープンソースツール](https://github.com/awslabs/amazon-neptune-tools/tree/master/graphml2csv)があります。

さまざまな APOC プロシージャを使用して、データを Amazon S3 に直接エクスポートすることもできます。Amazon S3 バケットへのエクスポートはデフォルトでは無効になっていますが、Neo4j APOC ドキュメントの「[Amazon S3 へのエクスポート](https://neo4j.com/labs/apoc/4.3/export/csv/#export-csv-s3-export)」で説明されている手順を使用して有効にできます。

## Neptune への移行時に Neo4j からデータをインポートする
<a name="migration-data-importing"></a>

Neptune にデータをインポートするには、[Neptune バルクローダー](bulk-load.md)を使用するか、[openCypher](access-graph-opencypher.md) など, サポートされているクエリ言語のアプリケーションロジックを使用します。

Neptune バルクローダーは、大量のデータをインポートする場合に推奨される方法であり、[ベストプラクティス](bulk-load-optimize.md)に従えば、インポートパフォーマンスが最適化されます。バルクローダーは [2 種類の CSV 形式](bulk-load-tutorial-format.md)をサポートしており、Neo4j からエクスポートされたデータは、[データのエクスポート](#migration-data-exporting) セクションで説明したオープンソースユーティリティを使用して変換できます。

openCypher を使用して、解析、変換、インポート用のカスタムロジックでデータをインポートすることもできます。openCypher クエリは [HTTPS エンドポイント](access-graph-opencypher-queries.md) (推奨) または[ボルトドライバー](access-graph-opencypher-bolt.md)を使用して送信できます。