Klausa MERGE menulis data ke dalam graf dengan pola get-or-create, yaitu mencocokkan pola terlebih dahulu, lalu membuatnya apabila tidak ada yang cocok. Topik ini membahas perbedaan MERGE dengan CREATE, properti pencocokan di dalam pola, cabang ON CREATE SET dan ON MATCH SET, urutan constraint keunikan sebelum MERGE, serta penggunaan MERGE untuk relasi. Seluruh contoh dijalankan pada server Neo4j 2026.10 dengan dataset jaringan sosial modul ini. Setelah membacanya, penulisan data idempoten dapat disusun tanpa menimbulkan node duplikat.
Dataset contoh#
Seluruh contoh menggunakan dataset jaringan sosial kecil yang sama dengan topik lain pada modul ini, yaitu empat orang bernama Ali, Budi, Citra, dan Dewi, serta empat kota bernama Jakarta, Bandung, Surabaya, dan Medan. Orang tersimpan sebagai node :Person dengan properti name dan tahunLahir, sedangkan kota tersimpan sebagai node :Kota dengan properti name. Relasi :KENAL menghubungkan dua orang dengan tanggal perkenalan pada properti sejak, sedangkan relasi :DOMISILI menghubungkan orang dengan kota domisilinya. Beberapa contoh menggunakan label demo :AlatTulis yang dibersihkan pada awal atau akhir kuerinya, sehingga tidak meninggalkan data pada graf.
Dataset dimuat dari berkas setup.cypher berikut yang idempoten (idempotent), artinya aman dijalankan berulang kali. Isinya sama dengan berkas setup.cypher pada topik lain dalam modul ini. Sintaksnya dibahas pada topik membuat dan mengubah data, sehingga berkas ini cukup dijalankan apa adanya.
// 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.
MERGE (ali:Person {name: "Ali"})
SET ali.tahunLahir = 1990;
MERGE (budi:Person {name: "Budi"})
SET budi.tahunLahir = 1988;
MERGE (citra:Person {name: "Citra"})
SET citra.tahunLahir = 1992;
MERGE (dewi:Person {name: "Dewi"})
SET dewi.tahunLahir = 1985;
// 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 neo4jPerilaku get-or-create#
MERGE mencari seluruh pola yang dituliskan pada graf terlebih dahulu. Apabila ada subgraf yang cocok, MERGE mengikat variabelnya pada pola yang sudah ada tanpa membuat apa pun, sedangkan apabila tidak ada yang cocok, MERGE berperilaku seperti CREATE dan membuat pola tersebut. Konsekuensinya, pernyataan MERGE bersifat idempoten (idempotent), artinya dijalankan sepuluh kali sekalipun keadaan akhir grafnya tetap sama, sedangkan CREATE selalu menambah node baru pada setiap eksekusi. Kueri berikut menjalankan dua pernyataan MERGE yang identik setelah label demo dibersihkan.
MATCH (a:AlatTulis) DETACH DELETE a;
MERGE (a:AlatTulis {name: "Penghapus"});
MERGE (a:AlatTulis {name: "Penghapus"});
MATCH (a:AlatTulis)
RETURN count(a) AS jumlah;jumlah
1Keluaran menampilkan satu karena pernyataan MERGE kedua menemukan node hasil pernyataan pertama, sehingga tidak ada node tambahan yang dibuat. Tabel berikut merangkum perbedaan kedua klausa.
| Aspek | CREATE | MERGE |
|---|---|---|
| Pemeriksaan keberadaan | tidak dilakukan | pola dicari lebih dahulu |
| Hasil eksekusi berulang | node baru setiap kali | keadaan akhir yang sama |
| Kegunaan yang tepat | data yang memang baru | data dengan kunci alami |
Perbedaan tersebut menjadikan MERGE pilihan baku untuk data berkunci alami seperti nama orang, sedangkan CREATE digunakan apabila setiap eksekusi memang harus menghasilkan data baru.
Properti pola sebagai kunci pencocokan#
Seluruh properti yang dituliskan di dalam pola MERGE berperan sebagai kunci pencocokan. Pola dianggap cocok hanya apabila node membawa setiap properti tersebut dengan nilai yang sama, sehingga penambahan satu properti pun mengubah makna polanya. Properti semacam warna bukan identitas benda, melainkan isinya, sehingga tempatnya bukan di dalam pola. Kueri berikut menjalankan tiga pernyataan MERGE atas benda yang sama, yaitu penghapus, dengan komposisi properti yang berbeda pada setiap polanya.
MATCH (a:AlatTulis) DETACH DELETE a;
MERGE (:AlatTulis {name: "Penghapus"});
MERGE (:AlatTulis {name: "Penghapus", warna: "putih"});
MERGE (:AlatTulis {name: "Penghapus", warna: "hitam"});
MATCH (a:AlatTulis)
RETURN a.name AS nama, a.warna AS warna
ORDER BY warna;nama, warna
"Penghapus", "hitam"
"Penghapus", "putih"
"Penghapus", NULLKeluaran memuat tiga node :AlatTulis untuk satu benda yang sama. Dua pola terakhir tidak menemukan kecocokan karena tidak ada node yang membawa properti warna, sehingga keduanya dibuat sebagai node baru. Duplikat seperti ini muncul meskipun seluruh pernyataannya menggunakan MERGE, dan terus bertambah pada setiap kombinasi properti baru.
Properti tambahan dengan ON CREATE dan ON MATCH SET#
Properti yang bukan kunci pencocokan diletakkan pada cabang ON CREATE SET dan ON MATCH SET. Cabang ON CREATE SET dijalankan hanya apabila pola tidak ditemukan dan dibuat baru, sedangkan cabang ON MATCH SET dijalankan hanya apabila pola ditemukan. Kueri berikut mengosongkan label demo, kemudian menjalankan MERGE yang membawa kedua cabang tersebut dalam satu pernyataan.
MATCH (a:AlatTulis) DETACH DELETE a;
MERGE (a:AlatTulis {name: "Penghapus"})
ON CREATE SET a.warna = "putih", a.stokAwal = 10
RETURN a.name AS nama, a.warna AS warna, a.stokAwal AS stokAwal, a.status AS status;nama, warna, stokAwal, status
"Penghapus", "putih", 10, NULLPada keluaran, warna dan stokAwal terisi karena node dibuat baru dan cabang ON CREATE SET berjalan, sedangkan status bernilai NULL karena cabang ON MATCH SET tidak pernah berjalan. Eksekusi berikutnya menempuh jalur pencocokan, sebagaimana kueri berikut yang memuat dua pernyataan.
MERGE (a:AlatTulis {name: "Penghapus"})
ON CREATE SET a.warna = "putih", a.stokAwal = 10;
MERGE (a:AlatTulis {name: "Penghapus"})
ON MATCH SET a.status = "tercatat";
MATCH (a:AlatTulis {name: "Penghapus"})
RETURN a.name AS nama, a.warna AS warna, a.status AS status;
MATCH (a:AlatTulis) DETACH DELETE a;nama, warna, status
"Penghapus", "putih", "tercatat"Nilai status kini terisi karena cabang ON MATCH SET berjalan pada jalur pencocokan, sedangkan warna tetap putih karena cabang pembuatan tidak dijalankan ulang. Nilai awal data dengan demikian diberikan pada ON CREATE SET, sedangkan pembaruan berkala pada ON MATCH SET. Pernyataan terakhir menghapus label demo agar percobaan tidak meninggalkan data pada graf.
Constraint keunikan sebelum MERGE#
MERGE menjamin pola ada setelah satu eksekusi, tetapi tidak menjamin keunikannya. Pada penulisan serentak, dua transaksi yang membawa pola identik dapat sama-sama tidak menemukan kecocokan, lalu sama-sama membuat node baru. Celah itu ditutup oleh constraint keunikan (uniqueness constraint), yaitu aturan yang ditegakkan mesin pada setiap penulisan sekaligus didukung indeks. Pernyataan berikut memasangnya pada properti name label :Person.
CREATE CONSTRAINT person_name_m2 IF NOT EXISTS
FOR (p:Person) REQUIRE p.name IS UNIQUE;
SHOW CONSTRAINTS YIELD name
WHERE name = "person_name_m2"
RETURN name;name
"person_name_m2"Klausa IF NOT EXISTS menjaga pernyataan tetap aman dijalankan ulang karena constraint yang ada tidak dibuat ulang. Dengan constraint tersebut, penulisan yang bertentangan ditolak mesin dengan pesan error, sehingga penulisan serentak atas kunci yang sama hanya menghasilkan satu node. Kueri berikut menjalankan MERGE atas orang yang sudah ada.
MERGE (p:Person {name: "Ali"});
MATCH (p:Person {name: "Ali"})
RETURN p.name AS nama, count(p) AS jumlah;nama, jumlah
"Ali", 1Keluaran tetap satu karena node Ali memang sudah ada, sehingga MERGE mengikat variabelnya tanpa membuat node tambahan. Urutan yang benar dengan demikian adalah constraint lebih dahulu dan MERGE sesudahnya.
MERGE untuk relasi#
Pola yang dicari MERGE juga mencakup relasi. Aturan utamanya adalah mengikat kedua node ujung terlebih dahulu dengan MATCH, kemudian menuliskan pola relasinya pada MERGE, sebagaimana pola relasi pada setup.cypher. Kueri berikut menghubungkan Dewi dan Budi dengan relasi :KENAL yang belum tersimpan pada dataset, lengkap dengan tanggal perkenalan pada cabang ON CREATE SET. Pernyataan yang sama dijalankan dua kali untuk membuktikan sifat idempotennya, dan pernyataan terakhir menghapus relasi percobaan agar dataset kembali ke bentuk aslinya.
MATCH (dewi:Person {name: "Dewi"}), (budi:Person {name: "Budi"})
MERGE (dewi)-[r:KENAL]->(budi)
ON CREATE SET r.sejak = date("2022-05-14");
MATCH (dewi:Person {name: "Dewi"}), (budi:Person {name: "Budi"})
MERGE (dewi)-[r:KENAL]->(budi)
ON CREATE SET r.sejak = date("2022-05-14");
MATCH (:Person {name: "Dewi"})-[r:KENAL]->(:Person {name: "Budi"})
RETURN count(r) AS jumlah;
MATCH (:Person {name: "Dewi"})-[r:KENAL]->(:Person {name: "Budi"})
DELETE r;jumlah
1Keluaran tetap satu karena relasi yang dibuat pada eksekusi pertama ditemukan kembali oleh eksekusi kedua, sehingga tidak ada relasi ganda yang terbentuk. Apabila pola relasi ditulis tanpa node ujung yang sudah terikat, MERGE tidak menemukan kecocokan apa pun, sehingga dua node anonim beserta relasinya dibuat pada setiap eksekusi. Properti sejak mengikuti aturan properti node, yaitu terisi hanya pada jalur pembuatan melalui ON CREATE SET, sehingga tanggal perkenalan tidak ditulis ulang pada eksekusi berikutnya.
Kesalahan umum#
Empat kesalahan berikut paling sering muncul saat topik ini dipraktikkan.
- Properti tambahan ditulis di dalam pola
MERGE. Pola{name: "Penghapus", warna: "putih"}dan{name: "Penghapus", warna: "hitam"}dianggap dua pola berbeda, sehingga tiga node muncul untuk satu benda sebagaimana keluaran sebelumnya. Perbaikannya adalah menuliskan hanya kunci pencocokan, lalu memindahkan properti lainnya keON CREATE SETatauON MATCH SET. CREATEdigunakan untuk data berkunci alami. Dua pernyataanCREATEyang identik menghasilkan node duplikat yang bertambah terus pada setiap eksekusi. Perbaikannya adalah menggunakanMERGEyang mencari dahulu sebelum membuat.MERGEdigunakan pada pola relasi tanpa mengikat node ujungnya. PernyataanMERGE (x)-[:KENAL]->(y)dengan variabel yang belum terikat tidak pernah menemukan kecocokan, sehingga dua node anonim beserta relasinya dibuat setiap eksekusi. Perbaikannya adalah menuliskanMATCHuntuk kedua node terlebih dahulu, kemudian pola relasinya padaMERGE.MERGEmassal dijalankan sebelum constraint keunikan terpasang. Duplikat dari penulisan serentak baru diketahui setelah data menumpuk, dan pembuatan constraint kemudian ditolak karena datanya sudah ganda. Perbaikannya adalah memasang constraint sejak awal, sebelumMERGEpertama dijalankan.
Ringkasan#
MERGEmencari pola lebih dahulu, lalu membuatnya apabila tidak ada yang cocok, sehingga pernyataannya idempoten pada eksekusi berulang.- Seluruh properti di dalam pola
MERGEadalah kunci pencocokan, sedangkan properti tambahan diberikan melaluiON CREATE SETpada jalur pembuatan danON MATCH SETpada jalur pencocokan. - Constraint keunikan pada properti kunci dibuat sebelum
MERGEdijalankan agar penulisan serentak tidak meloloskan duplikat dan pencariannya didukung indeks. - Relasi dituliskan pada
MERGEsetelah kedua node ujungnya diikat melaluiMATCH, sehingga pola relasi menemukan node yang sudah ada dan tidak membuat node anonim baru.
Referensi#
- MERGE — Neo4j Docs
— Referensi klausa
MERGEbeserta cabangON CREATEdanON MATCHserta anjuran membuat constraint sebelum data digabungkan. - Create constraints — Neo4j Docs
— Sintaks
CREATE CONSTRAINT, klausaIF NOT EXISTS, dan constraint keunikan yang melindungi pencocokanMERGE.