Saya mencoba membuat kueri menggunakan cypher yang akan "Menemukan" bahan yang hilang yang mungkin dimiliki koki, Grafik saya disiapkan seperti ini:
(ingredient_value)-[:is_part_of]->(ingredient)
(ingredient)
akan memiliki kunci / nilai name = "warna pewarna". (ingredient_value)
bisa memiliki kunci / nilai value = "red" dan "adalah bagian dari" the (ingredient, name="dye colors")
.
(chef)-[:has_value]->(ingredient_value)<-[:requires_value]-(recipe)-[:requires_ingredient]->(ingredient)
Saya menggunakan kueri ini untuk mendapatkan semua ingredients
, tapi bukan nilai sebenarnya, yang dibutuhkan resep, tapi saya ingin mengembalikan hanya ingredients
yang tidak dimiliki koki, alih-alih semua bahan yang dibutuhkan setiap resep. Saya mencoba
(chef)-[:has_value]->(ingredient_value)<-[:requires_value]-(recipe)-[:requires_ingredient]->(ingredient)<-[:has_ingredient*0..0]-chef
tapi ini tidak menghasilkan apa-apa.
Apakah ini sesuatu yang dapat dicapai oleh cypher / neo4j atau apakah ini sesuatu yang paling baik ditangani dengan mengembalikan semua bahan dan menyortirnya sendiri?
Bonus: Juga apakah ada cara untuk menggunakan cypher untuk mencocokkan semua nilai yang dimiliki koki dengan semua nilai yang dibutuhkan resep. Sejauh ini saya hanya mengembalikan semua pertandingan parsial yang dikembalikan oleh chef-[:has_value]->ingredient_value<-[:requires_value]-recipe
dan menggabungkan hasilnya sendiri.
exists
dalamWHERE
klausa (juga meniadakannya), neo4j.com/developer/subqueries/#existential-subqueries untuk informasi lebih lanjut.Jawaban:
Pembaruan 01/10/2013:
Temukan ini di referensi Neo4j 2.0 :
Cobalah untuk tidak menggunakan hubungan opsional. Diatas segalanya,
jangan gunakan mereka seperti ini:
MATCH a-[r?:LOVES]->() WHERE r IS NULL
di mana Anda hanya memastikan bahwa mereka tidak ada.Sebagai gantinya lakukan ini seperti:
Menggunakan cypher untuk memeriksa apakah hubungan tidak ada:
Itu? mark membuat hubungan itu opsional.
ATAU
Di neo4j 2 lakukan:
Sekarang Anda dapat memeriksa hubungan yang tidak ada (null).
sumber
MATCH a...
contoh sekarang harusMATCH (a) WHERE NOT (a)-[:LOVES]->()
Untuk mengambil node yang tidak memiliki hubungan apa pun
Ini adalah opsi yang baik untuk memeriksa apakah hubungan ada atau tidak
Anda juga dapat memeriksa beberapa kondisi untuk ini. Ini akan mengembalikan semua node, yang tidak memiliki Hubungan "memainkan" atau "notPlayed".
Untuk mengambil node yang tidak memiliki hubungan apapun
Ini akan memeriksa node tidak memiliki hubungan masuk / keluar.
sumber
MATCH (player) WHERE NOT (player)-[r]-() RETURN player
memberikan Variabel r tidak didefinisikan kesalahan. Bagaimana saya bisa mendefinisikan r?(player -[:rel]- ()
) atau kosongkan untuk hubungan apa pun(player -[]- ()
MATCH (player) WHERE NOT (player)-[]-() RETURN player
- Ini berfungsi dengan baikJika Anda membutuhkan semantik "pengecualian bersyarat", Anda dapat mencapainya dengan cara ini.
Pada neo4j 2.2.1, Anda dapat menggunakan
OPTIONAL MATCH
klausa dan memfilterNULL
simpul yang tidak cocok ( ).Penting juga untuk menggunakan
WITH
klausa antara klausaOPTIONAL MATCH
danWHERE
, sehingga klausa pertamaWHERE
mendefinisikan kondisi untuk kecocokan opsional dan klausa keduaWHERE
berperilaku seperti filter.Dengan asumsi kami memiliki 2 jenis node:
Person
danCommunication
. Jika saya ingin mendapatkan semua Orang yang tidak pernah berkomunikasi melalui telepon, tetapi mungkin telah berkomunikasi dengan cara lain, saya akan membuat pertanyaan ini:Pola pencocokan akan mencocokkan semua Orang dengan komunikasinya di mana
c
akanNULL
untuk Komunikasi non-telepon. Kemudian filter (WHERE
setelahWITH
) akan menyaring Komunikasi telepon meninggalkan yang lainnya.Referensi:
http://neo4j.com/docs/stable/query-optional-match.html#_introduction_3 http://java.dzone.com/articles/new-neo4j-optional
sumber
Saya menulis inti yang menunjukkan bagaimana hal ini dapat dilakukan secara alami menggunakan Cypher 2.0
http://gist.neo4j.org/?9171581
Poin utamanya adalah menggunakan pencocokan opsional untuk bahan-bahan yang tersedia dan kemudian membandingkannya dengan menyaring bahan-bahan yang hilang (nol) atau bahan-bahan dengan nilai yang salah.
Perhatikan bahwa gagasan ini bersifat deklaratif dan tidak perlu menjelaskan algoritme, Anda cukup menuliskan apa yang Anda butuhkan.
sumber
Saya menyelesaikan tugas ini menggunakan gremlin. aku melakukannya
Ini mengembalikan jalur semua bahan yang hilang. Saya tidak dapat merumuskan ini dalam bahasa sandi, setidaknya untuk versi 1.7.
sumber
Kueri terakhir harus:
Pola ini:
(ingredient)<-[:has_ingredient*0..0]-chef
Apakah alasan itu tidak mengembalikan apa pun.
*0..0
berarti panjang hubungan harus nol, yang berarti bahan dan chef harus berada dalam simpul yang sama, padahal bukan.sumber