Hasil kueri Cypher jarang ditampilkan apa adanya. Baris yang tidak relevan perlu disaring, nilai ganda perlu dipilah, dan urutan baris perlu dikunci sebelum keluaran dikirim ke aplikasi. Topik ini membahas klausa WHERE untuk penyaringan baris, DISTINCT untuk pemilahan nilai ganda, ORDER BY dan LIMIT untuk pengurutan serta pembatasan, dan proyeksi RETURN untuk membentuk kolom keluaran melalui alias, ekspresi, dan peta nilai. Setiap contoh dijalankan pada dataset modul ini, sehingga keluarannya dapat direproduksi ulang.
Dataset contoh#
Seluruh contoh menggunakan dataset jaringan sosial yang sudah dimuat pada topik pola dalam MATCH, yaitu empat orang bernama Ali, Budi, Citra, dan Dewi, serta empat kota bernama Jakarta, Bandung, Surabaya, dan Medan. Setiap orang disimpan sebagai node berlabel :Person, setiap kota sebagai node berlabel :Kota, relasi :KENAL menyimpan tanggal perkenalan pada properti sejak, dan relasi :DOMISILI menghubungkan orang dengan kota tinggalnya. Topik ini menambahkan properti umur pada Ali, Citra, dan Dewi, sedangkan umur Budi sengaja tidak dicatat agar nilai null, yaitu penanda nilai yang tidak ada, ikut tersedia di dalam dataset. Nilai umur dituliskan secara statis, dan tahunLahir tetap disimpan karena digunakan pada bagian proyeksi RETURN.
Berkas setup.cypher berikut memuat dataset tersebut secara idempoten (idempotent), artinya aman dijalankan berulang kali karena data yang sudah ada tidak dibuat ulang. Jalankan berkasnya melalui cypher-shell sebelum mencoba kueri pada bagian berikutnya. Seluruh kueri pada topik ini hanya membaca data, sehingga tidak ada perubahan yang perlu dibatalkan.
// Dataset contoh modul Fundamental Cypher: jaringan sosial kecil
// dengan empat orang dan empat kota.
// Skrip ini idempoten (idempotent), artinya aman dijalankan berulang kali.
// Node orang: label :Person dengan properti name dan tahunLahir.
// Umur Budi sengaja tidak dicatat agar contoh nilai null tetap tersedia.
MERGE (ali:Person {name: "Ali"})
SET ali.tahunLahir = 1990, ali.umur = 36;
MERGE (budi:Person {name: "Budi"})
SET budi.tahunLahir = 1988;
MERGE (citra:Person {name: "Citra"})
SET citra.tahunLahir = 1992, citra.umur = 34;
MERGE (dewi:Person {name: "Dewi"})
SET dewi.tahunLahir = 1985, dewi.umur = 41;
// Node kota: label :Kota dengan properti name.
MERGE (jakarta:Kota {name: "Jakarta"});
MERGE (bandung:Kota {name: "Bandung"});
MERGE (surabaya:Kota {name: "Surabaya"});
MERGE (medan:Kota {name: "Medan"});
// Relasi KENAL berarah antar orang, dengan properti sejak.
MATCH (ali:Person {name: "Ali"}), (budi:Person {name: "Budi"})
MERGE (ali)-[r:KENAL]->(budi)
SET r.sejak = date("2019-03-10");
MATCH (ali:Person {name: "Ali"}), (citra:Person {name: "Citra"})
MERGE (ali)-[r:KENAL]->(citra)
SET r.sejak = date("2021-01-15");
MATCH (budi:Person {name: "Budi"}), (citra:Person {name: "Citra"})
MERGE (budi)-[r:KENAL]->(citra)
SET r.sejak = date("2020-07-21");
MATCH (citra:Person {name: "Citra"}), (dewi:Person {name: "Dewi"})
MERGE (citra)-[r:KENAL]->(dewi)
SET r.sejak = date("2018-11-05");
MATCH (dewi:Person {name: "Dewi"}), (ali:Person {name: "Ali"})
MERGE (dewi)-[r:KENAL]->(ali)
SET r.sejak = date("2017-06-02");
// Relasi DOMISILI dari orang menuju kota tempat tinggalnya.
MATCH (ali:Person {name: "Ali"}), (jakarta:Kota {name: "Jakarta"})
MERGE (ali)-[:DOMISILI]->(jakarta);
MATCH (budi:Person {name: "Budi"}), (bandung:Kota {name: "Bandung"})
MERGE (budi)-[:DOMISILI]->(bandung);
MATCH (citra:Person {name: "Citra"}), (bandung:Kota {name: "Bandung"})
MERGE (citra)-[:DOMISILI]->(bandung);
MATCH (dewi:Person {name: "Dewi"}), (medan:Kota {name: "Medan"})
MERGE (dewi)-[:DOMISILI]->(medan);# tidak-dijalankan
# memuat dataset contoh dari berkas setup.cypher ke dalam basis data
cat setup.cypher | cypher-shell -u neo4jMenyaring baris dengan WHERE#
Klausa WHERE menyaring baris hasil MATCH dengan mengevaluasi sebuah predikat (predicate), yaitu ekspresi yang bernilai benar atau salah. Klausa ini ditulis setelah MATCH. Hanya baris pencocokan yang predikatnya bernilai benar yang dipertahankan. Operator perbandingannya mencakup =, <>, <, <=, >, dan >=, sedangkan rentang nilai ditulis sebagai dua perbandingan yang dirangkai AND, misalnya p.umur >= 30 AND p.umur <= 40. Kueri berikut mengambil orang yang umurnya dicatat minimal 35 tahun.
MATCH (p:Person)
WHERE p.umur >= 35
RETURN p.name AS nama, p.umur AS umur
ORDER BY nama;nama, umur
"Ali", 36
"Dewi", 41Keluaran hanya memuat Ali dan Dewi. Baris Budi tidak muncul karena p.umur bernilai null, dan perbandingan apa pun dengan null menghasilkan null, bukan benar atau salah. Hanya predikat bernilai benar yang mempertahankan baris, sehingga properti yang tidak tercatat tersaring keluar tanpa syarat tambahan.
Syarat majemuk dirangkai dengan operator boolean AND, OR, dan NOT. Operator AND mengikat lebih kuat daripada OR, sehingga tanda kurung diperlukan apabila pengelompokannya berbeda, sedangkan NOT membalik nilai kebenaran syarat yang mengikutinya. Pencocokan string disediakan melalui STARTS WITH, ENDS WITH, dan CONTAINS untuk memeriksa awalan, akhiran, dan bagian dalam sebuah nilai string, dan ketiganya peka terhadap huruf besar-kecil. Kueri berikut mencari orang yang domisilinya diawali “Ba” atau memuat “rta”.
MATCH (p:Person)-[:DOMISILI]->(k:Kota)
WHERE k.name STARTS WITH "Ba" OR k.name CONTAINS "rta"
RETURN p.name AS nama, k.name AS kota
ORDER BY nama;nama, kota
"Ali", "Jakarta"
"Budi", "Bandung"
"Citra", "Bandung"Predikat juga boleh ditulis di dalam pola node, misalnya (p:Person WHERE p.umur IS NOT NULL). Predikat IS NOT NULL bernilai benar hanya untuk node yang propertinya benar-benar ada. Bentuk ini menyatukan pola dan syarat, sehingga kueri berikut terbaca sebagai pencarian orang yang umurnya tercatat beserta orang yang dikenalinya.
MATCH (p:Person WHERE p.umur IS NOT NULL)-[:KENAL]->(teman)
RETURN p.name AS nama, teman.name AS dikenal
ORDER BY nama, dikenal;nama, dikenal
"Ali", "Budi"
"Ali", "Citra"
"Citra", "Dewi"
"Dewi", "Ali"Memilah nilai ganda dengan DISTINCT#
Klausa RETURN memetakan setiap baris pencocokan menjadi satu baris keluaran, sehingga nilai yang sama dapat muncul berkali-kali. Pengulangan semacam ini wajar, tetapi tidak selalu diinginkan pada keluaran akhir. Dua orang di dalam dataset tinggal di Bandung, karena relasi :DOMISILI dari Budi dan Citra mengarah ke kota yang sama. Kueri berikut memperlihatkan pengulangan itu.
MATCH (p:Person)-[:DOMISILI]->(k:Kota)
RETURN k.name AS kota
ORDER BY kota;kota
"Bandung"
"Bandung"
"Jakarta"
"Medan"Kata DISTINCT ditulis sebelum daftar proyeksi dan membuang baris duplikat, yaitu baris yang seluruh nilainya sama dengan baris lain yang sudah dikembalikan. Keunikannya dinilai atas kombinasi seluruh kolom dalam satu baris, bukan kolom per kolom, sehingga RETURN DISTINCT p.name, k.name tetap dapat mengembalikan nama yang sama apabila kota-kotanya berbeda. Kueri yang sama dengan DISTINCT menyisakan tiga kota.
MATCH (p:Person)-[:DOMISILI]->(k:Kota)
RETURN DISTINCT k.name AS kota
ORDER BY kota;kota
"Bandung"
"Jakarta"
"Medan"Pemilahan seperti ini lazim sebelum hasil digunakan lebih lanjut, misalnya untuk mengisi daftar pilihan pada aplikasi yang tidak memerlukan nilai ganda.
Mengurutkan dan membatasi dengan ORDER BY dan LIMIT#
Tanpa ORDER BY, urutan baris keluaran tidak dijamin. Klausa ORDER BY ditulis setelah RETURN dan mengurutkan baris menurut satu atau beberapa ekspresi yang dipisahkan koma, misalnya ORDER BY nama, umur yang mengurutkan menurut nama lebih dahulu. Urutan bawaannya menaik, dan kata DESC mengubahnya menjadi menurun. Ekspresi yang diurutkan boleh berupa kolom proyeksi maupun properti yang tidak ikut dikembalikan. Kueri berikut mengurutkan orang menurut umurnya.
MATCH (p:Person)-[:DOMISILI]->(k:Kota)
RETURN p.name AS nama, p.umur AS umur
ORDER BY umur;nama, umur
"Citra", 34
"Ali", 36
"Dewi", 41
"Budi", NULLBaris Budi menempati posisi terakhir karena p.umur bernilai null. Cypher menempatkan null di akhir urutan menaik dan di awal urutan menurun, sehingga posisinya berpindah ketika arah pengurutan dibalik. Apabila posisi null mengganggu pembacaan, saring barisnya terlebih dahulu dengan IS NOT NULL.
MATCH (p:Person)-[:DOMISILI]->(k:Kota)
RETURN p.name AS nama, p.umur AS umur
ORDER BY umur DESC;nama, umur
"Budi", NULL
"Dewi", 41
"Ali", 36
"Citra", 34Klausa LIMIT ditulis setelah ORDER BY dan menyisakan sejumlah baris pertama saja. Rangkaian menyaring dengan WHERE, mengurutkan dengan ORDER BY, lalu membatasi dengan LIMIT membentuk alur kerja yang lazim pada aplikasi. Kombinasi ini juga membuat keluaran menjadi pasti, karena pembatasan bekerja di atas urutan yang sudah dikunci. Kueri berikut mengambil dua orang tertua yang umurnya tercatat.
MATCH (p:Person)
WHERE p.umur IS NOT NULL
RETURN p.name AS nama, p.umur AS umur
ORDER BY umur DESC
LIMIT 2;nama, umur
"Dewi", 41
"Ali", 36Membentuk hasil dengan proyeksi RETURN#
Bentuk keluaran ditentukan oleh proyeksi pada klausa RETURN. Setiap item proyeksi dapat diberi alias melalui kata AS, yaitu nama kolom baru yang tampil pada header keluaran. Alias juga memberi nama pada hasil sebuah ekspresi, sebagaimana kueri berikut yang menghitung perkiraan umur dari tahunLahir.
MATCH (p:Person)-[:DOMISILI]->(k:Kota)
RETURN p.name AS nama, k.name AS kota, 2026 - p.tahunLahir AS perkiraanUmur
ORDER BY nama;nama, kota, perkiraanUmur
"Ali", "Jakarta", 36
"Budi", "Bandung", 38
"Citra", "Bandung", 34
"Dewi", "Medan", 41Kolom perkiraanUmur dihasilkan ekspresi aritmetika 2026 - p.tahunLahir, dan angka 2026 ditulis langsung agar keluaran tetap sama pada setiap eksekusi. Nilai yang dihitung itu cocok dengan properti umur untuk tiga orang, sedangkan Budi yang umurnya tidak dicatat tetap memperoleh angka dari tahun lahirnya.
Bentuk proyeksi ketiga adalah peta nilai (map projection), yaitu objek berkurung kurawal yang dibangun dari sebuah variabel. Notasi .name menyertakan properti name apa adanya, sedangkan kunci: ekspresi membuat kunci baru dari sebuah ekspresi. Kueri berikut merangkum setiap orang beserta kota domisilinya menjadi satu nilai peta.
MATCH (p:Person)-[:DOMISILI]->(k:Kota)
RETURN p { .name, .umur, domisili: k.name } AS profil
ORDER BY p.name;profil
{name: "Ali", domisili: "Jakarta", umur: 36}
{name: "Budi", domisili: "Bandung", umur: NULL}
{name: "Citra", domisili: "Bandung", umur: 34}
{name: "Dewi", domisili: "Medan", umur: 41}Satu kolom peta menghimpun beberapa fakta sekaligus, sehingga praktis dijadikan respons API. Kunci di dalam peta tidak menyimpan urutan, sehingga urutan tampil pada keluaran dapat berbeda dari urutan penulisannya. Properti yang tidak ada menghasilkan kunci bernilai null, sebagaimana umur pada peta Budi.
Kesalahan umum#
- Memperlakukan perbandingan dengan null sebagai salah. Predikat
p.umur > 30pada baris yang umurnya null bernilai null, bukan salah, danNOTatas null juga tetap null, sehingga baris itu tersaring keluar dari kueri mana pun. Keluaran yang kosong padahal data seharusnya ada biasanya berasal dari perilaku ini. Tangani kondisi properti yang tidak ada secara eksplisit denganIS NOT NULLsebelum perbandingannya, sedangkanIS NULLberlaku sebaliknya, yaitu bernilai benar hanya untuk properti yang tidak ada. - Menulis
LIMITtanpaORDER BY. Urutan baris tanpa pengurutan tidak dijamin, sehingga baris yang tersisa dapat berbeda antar eksekusi.LIMIT 5tanpa pengurutan bukan lima baris terbaik, melainkan lima baris apa pun. PasangkanLIMITdenganORDER BYyang menegaskan makna baris teratasnya. - Mengira
DISTINCTmenyatukan node. ProyeksiRETURN DISTINCT ptetap mengembalikan satu baris untuk setiap node karena dua node berbeda dianggap dua nilai yang berbeda. Pilah propertinya sebagai gantinya, misalnyaRETURN DISTINCT p.name.
Ringkasan#
WHEREmenyaring baris pencocokan dengan predikat, perbandingan yang melibatkan null menghasilkan null sehingga barisnya tersaring keluar, danIS NULLatauIS NOT NULLmenangani kondisi tersebut secara eksplisit.DISTINCTmembuang baris yang kombinasi nilai seluruh kolomnya sama dengan baris lain.ORDER BYmengunci urutan baris, menaik secara bawaan atau menurun melaluiDESC, dengan null di akhir urutan menaik dan di awal urutan menurun, sedangkanLIMITmenyisakan sejumlah baris pertama.- Proyeksi
RETURNmembentuk kolom keluaran melalui aliasAS, ekspresi aritmetika, dan peta nilai yang menghimpun beberapa properti dalam satu kolom.
Referensi#
- WHERE — Neo4j Docs
— Referensi klausa
WHEREbeserta predikat perbandingan, operator boolean, dan pencocokan string. - RETURN — Neo4j Docs
— Referensi proyeksi
RETURN, termasukDISTINCT, alias, ekspresi, dan peta nilai. - ORDER BY — Neo4j Docs — Referensi pengurutan baris keluaran beserta penempatan nilai null.