

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Menulis ulang kueri Cypher untuk dijalankan di OpenCypher di Neptunus
<a name="migration-opencypher-rewrites"></a>

[Bahasa OpenCypher adalah bahasa query deklaratif untuk grafik properti yang awalnya dikembangkan oleh Neo4j, kemudian open-source pada tahun 2015, dan berkontribusi pada proyek OpenCypher di bawah lisensi open-source Apache 2.](https://www.opencypher.org/) Di AWS, kami percaya bahwa open source baik untuk semua orang dan kami berkomitmen untuk membawa nilai open source kepada pelanggan kami, dan keunggulan operasional AWS untuk komunitas open source.

OpenCypher sintaks didokumentasikan dalam [Referensi Bahasa Kueri Cypher, Versi 9](https://s3.amazonaws.com/artifacts.opencypher.org/openCypher9.pdf).

Karena OpenCypher berisi subset sintaks dan fitur bahasa kueri Cypher, beberapa skenario migrasi memerlukan penulisan ulang kueri dalam formulir yang sesuai dengan OpenCypher atau memeriksa metode alternatif untuk mencapai fungsionalitas yang diinginkan.

Bagian ini berisi rekomendasi untuk menangani perbedaan umum, tetapi sama sekali tidak lengkap. Anda harus menguji aplikasi apa pun menggunakan penulisan ulang ini secara menyeluruh untuk memastikan bahwa hasilnya sesuai dengan yang Anda harapkan.

## Menulis ulang`None`,`All`, dan fungsi `Any` predikat
<a name="migration-opencypher-rewrites-none-all-any"></a>

Fungsi-fungsi ini bukan bagian dari spesifikasi OpenCypher. Hasil yang sebanding dapat dicapai di OpenCypher menggunakan List Comprehension.

Misalnya, temukan semua jalur yang berpindah dari node `Start` ke node`End`, tetapi tidak ada perjalanan yang diizinkan melewati node dengan properti kelas`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
```

Pemahaman daftar dapat mencapai hasil ini sebagai berikut:

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

## Menulis ulang fungsi Cypher di OpenCypher `reduce()`
<a name="migration-opencypher-rewrites-reduce"></a>

`reduce()`Fungsi ini bukan bagian dari spesifikasi OpenCypher. Hal ini sering digunakan untuk membuat agregasi data dari elemen dalam daftar. Dalam banyak kasus, Anda dapat menggunakan kombinasi Pemahaman Daftar dan `UNWIND` klausa untuk mencapai hasil yang serupa.

Misalnya, kueri Cypher berikut menemukan semua bandara di jalur yang memiliki satu hingga tiga pemberhentian antara Anchorage (ANC) dan Austin (AUS), dan mengembalikan jarak total setiap jalur:

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

Anda dapat menulis kueri yang sama di OpenCypher untuk Neptunus sebagai berikut:

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

## Menulis ulang klausa Cypher FOREACH di OpenCypher
<a name="migration-opencypher-rewrites-foreach"></a>

Klausa FOREACH bukan bagian dari spesifikasi OpenCypher. Hal ini sering digunakan untuk memperbarui data di tengah-tengah query, sering dari agregasi atau elemen dalam jalur.

Sebagai contoh jalur, temukan semua bandara di jalur dengan tidak lebih dari dua pemberhentian antara Anchorage (ANC) dan Austin (AUS) dan tetapkan properti yang dikunjungi di masing-masing bandara:

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

Contoh lain adalah:

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

## Menulis ulang prosedur APOC Neo4j di Neptunus
<a name="migration-opencypher-rewrites-apoc"></a>

[Contoh di bawah ini menggunakan OpenCypher untuk menggantikan beberapa prosedur APOC yang paling umum digunakan.](https://neo4j.com/blog/intro-user-defined-procedures-apoc/) Contoh-contoh ini hanya untuk referensi, dan dimaksudkan untuk memberikan beberapa saran tentang cara menangani skenario umum. Dalam praktiknya, setiap aplikasi berbeda, dan Anda harus membuat strategi Anda sendiri untuk menyediakan semua fungsionalitas yang Anda butuhkan.

### Prosedur penulisan ulang `apoc.export`
<a name="migration-opencypher-rewrites-apoc-export"></a>

[Neptunus menyediakan berbagai opsi untuk grafik penuh dan ekspor berbasis kueri dalam berbagai format output seperti CSV dan JSON, menggunakan utilitas ekspor neptunus (lihat).](https://github.com/aws/neptune-export) [Mengekspor data dari cluster DB Neptunus](neptune-data-export.md)

### Prosedur penulisan ulang `apoc.schema`
<a name="migration-opencypher-rewrites-apoc-schema"></a>

Neptunus tidak memiliki skema, indeks, atau kendala yang didefinisikan secara eksplisit, sehingga banyak prosedur tidak lagi diperlukan. `apoc.schema` Contohnya adalah:
+ `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`

Neptunus OpenCypher memang mendukung pengambilan nilai yang serupa dengan yang dilakukan prosedur, seperti yang ditunjukkan di bawah ini, tetapi dapat mengalami masalah kinerja pada grafik yang lebih besar karena hal itu memerlukan pemindaian sebagian besar grafik untuk mengembalikan jawabannya.

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

### Alternatif untuk `apoc.do` prosedur
<a name="migration-opencypher-rewrites-apoc-do"></a>

Prosedur ini digunakan untuk menyediakan eksekusi kueri bersyarat yang mudah diimplementasikan menggunakan klausa OpenCypher lainnya. Di Neptunus setidaknya ada dua cara untuk mencapai perilaku serupa:
+ Salah satu caranya adalah dengan menggabungkan kemampuan Pemahaman Daftar OpenCypher dengan klausa. `UNWIND`
+ Cara lain adalah dengan menggunakan langkah choose () dan coalesce () di Gremlin.

Contoh pendekatan ini ditunjukkan di bawah ini.

#### Alternatif untuk 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())
```

#### Alternatif untuk 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())
```

## Alternatif untuk properti berbasis daftar
<a name="migration-opencypher-rewrites-lists"></a>

Neptunus saat ini tidak mendukung penyimpanan properti berbasis Daftar. Namun, hasil serupa dapat diperoleh dengan menyimpan nilai daftar sebagai string yang dipisahkan koma dan kemudian menggunakan `split()` fungsi `join()` and untuk membangun dan mendekonstruksi properti list.

Misalnya, jika kita ingin menyimpan daftar tag sebagai properti, kita dapat menggunakan contoh penulisan ulang yang menunjukkan cara mengambil properti yang dipisahkan koma dan kemudian menggunakan `join()` fungsi `split()` dan dengan Pemahaman Daftar untuk mencapai hasil yang sebanding:

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

## Menulis ulang subkueri CALL
<a name="migration-opencypher-rewrites-call-subqueries"></a>

 Subquery `CALL` Neptunus tidak mendukung `CALL (friend) { ... }` sintaks untuk mengimpor variabel ke dalam lingkup subquery (, dalam contoh ini). `friend` Silakan gunakan `WITH` klausa di dalam subquery untuk hal yang sama, misalnya,. `CALL { WITH friend ... }` 

 `CALL`Subquery opsional tidak didukung saat ini. 

## Perbedaan lain antara Neptunus OpenCypher dan Cypher
<a name="opencypher-compliance-other-differences"></a>
+ Neptunus hanya mendukung koneksi TCP untuk protokol Bolt. WebSocketskoneksi untuk Bolt tidak didukung.
+ Neptune OpenCypher menghapus spasi seperti yang didefinisikan oleh Unicode di, dan fungsi. `trim()` `ltrim()` `rtrim()`
+ Di Neptunus OpenCypher`tostring(`, `)` ganda tidak secara otomatis beralih ke notasi E untuk nilai ganda yang besar.