Menulis ulang pertanyaan Cypher untuk dijalankan di OpenCypher di Neptune - Amazon Neptune

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

Menulis ulang pertanyaan Cypher untuk dijalankan di OpenCypher di Neptune

Bahasa OpenCypher adalah bahasa kueri 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. DiAWS, kami percaya bahwa open source baik untuk semua orang dan kami berkomitmen untuk membawa nilai open source kepada pelanggan kami, dan keunggulan operasionalAWS untuk komunitas open source.

OpenCypher sintaks didokumentasikan dalam Referensi Cypher Query Language, Versi 9.

Karena OpenCypher berisi subset dari 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, namun sama sekali tidak lengkap. Anda harus menguji aplikasi apa pun menggunakan penulisan ulang ini secara menyeluruh untuk memastikan bahwa hasilnya adalah apa yang Anda harapkan.

Menulis ulangNone,All, dan fungsiAny predikat

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

Misalnya, menemukan semua jalur yang pergi dari nodeStart ke nodeEnd, tetapi tidak ada perjalanan diperbolehkan untuk melewati node dengan properti kelasD:

# 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 ulangreduce() fungsi Cypher di OpenCypher

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

Misalnya, kueri Cypher berikut menemukan semua bandara di jalur yang memiliki satu hingga tiga stop 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 query yang sama di OpenCypher untuk Neptune 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

Klausa FOREACH bukan bagian dari spesifikasi OpenCypher. Hal ini sering digunakan untuk memperbarui data di 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 atur properti yang dikunjungi pada masing-masing:

# 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 lainnya 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 Neo4j APOC di Neptune

Contoh di bawah ini menggunakan OpenCypher untuk mengganti beberapa prosedur APOC yang paling umum digunakan. 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 fungsi yang Anda butuhkan.

apoc.exportProsedur penulisan ulang

Neptune menyediakan berbagai pilihan untuk grafik penuh dan ekspor berbasis query dalam berbagai format output seperti CSV dan JSON, menggunakan utilitas neptune-ekspor (lihatMengekspor data dari klaster DB Neptune).

apoc.schemaProsedur penulisan ulang

Neptune tidak memiliki skema, indeks, atau kendala yang didefinisikan secara eksplisit, sehingga banyakapoc.schema prosedur tidak lagi diperlukan. Contoh 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

Neptune OpenCypher mendukung pengambilan nilai yang sama 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 untukapoc.do prosedur

Prosedur ini digunakan untuk menyediakan eksekusi query kondisional yang mudah diterapkan menggunakan klausa OpenCypher lainnya. Di Neptune setidaknya ada dua cara untuk mencapai perilaku serupa:

  • Salah satu caranya adalah dengan menggabungkan kemampuan List Comprehension OpenCypher denganUNWIND klausa.

  • Cara lain adalah dengan menggunakan langkah choose () dan coalesce () di Gremlin.

Contoh pendekatan ini ditunjukkan di bawah ini.

Alternatif untuk apoc.do.when

# 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

# 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

Neptune saat ini tidak mendukung penyimpanan properti berbasis Daftar. Namun, hasil yang sama dapat diperoleh dengan menyimpan nilai daftar sebagai string dipisahkan komajoin() dan kemudian menggunakansplit() fungsi dan untuk membangun dan mendekonstruksi properti daftar.

Misalnya, jika kita ingin menyimpan daftar tag sebagai properti, kita bisa menggunakan contoh menulis ulang yang menunjukkan bagaimana untuk mengambil properti dipisahkan koma dan kemudian menggunakanjoin() fungsisplit() dan dengan Daftar Comprehension 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