1. Ikhtisar
Terkadang, kita memerlukan ID dari dokumen yang baru saja kita masukkan ke dalam database MongoDB. Misalnya, kami mungkin ingin mengirim kembali ID sebagai respons ke pemanggil atau mencatat objek yang dibuat untuk debugging.
Dalam tutorial ini, kita akan melihat bagaimana ID diimplementasikan di MongoDB dan bagaimana mengambil ID dari dokumen yang baru saja kita sisipkan ke dalam koleksi melalui program Java.
2. Apa ID Dokumen MongoDB?
Seperti di setiap sistem penyimpanan data, MongoDB membutuhkan pengenal unik untuk setiap dokumen yang disimpan dalam koleksi. Pengenal ini setara dengan kunci utama dalam database relasional.
Di MongoDB, ID ini terdiri dari 12 byte:
- nilai cap waktu 4-byte mewakili detik sejak zaman Unix
- nilai acak 5 byte yang dihasilkan sekali per proses. Nilai acak ini unik untuk mesin dan prosesnya.
- penghitung kenaikan 3 byte
ID disimpan di bidang bernama _id dan dibuat oleh klien. Ini berarti bahwa ID harus dibuat sebelum mengirim dokumen ke database. Di sisi klien, kami dapat menggunakan ID yang dibuat oleh driver atau membuat ID khusus.
Kita dapat melihat bahwa dokumen yang dibuat oleh klien yang sama dalam detik yang sama akan memiliki 9 byte pertama yang sama. Karena itu, keunikan ID bergantung pada penghitung dalam hal ini. Penghitung memungkinkan klien membuat lebih dari 16 juta dokumen dalam hitungan detik.
Meskipun dimulai dengan stempel waktu, kita harus berhati-hati agar pengenal tidak digunakan sebagai kriteria pengurutan. Ini karena dokumen yang dibuat dalam detik yang sama tidak dijamin akan diurutkan berdasarkan tanggal pembuatan, karena penghitungnya tidak dijamin monoton. Selain itu, klien yang berbeda mungkin memiliki jam sistem yang berbeda.
Driver Java menggunakan generator nomor acak untuk penghitung, yang tidak monoton. Itulah mengapa kita tidak boleh menggunakan ID yang dibuat oleh driver untuk mengurutkan berdasarkan tanggal pembuatan.
3. ObjectId Kelas
Pengidentifikasi unik disimpan dalam ObjectId class yang menyediakan metode mudah untuk mendapatkan data yang disimpan dalam ID tanpa menguraikannya secara manual.
Misalnya, berikut ini cara kami mendapatkan tanggal pembuatan ID:
Date creationDate = objectId.getDate();
Demikian juga, kami dapat mengambil stempel waktu ID dalam hitungan detik :
int timestamp = objectId.getTimestamp();
ObjectId class juga menyediakan metode untuk mendapatkan penghitung, pengidentifikasi mesin, atau pengidentifikasi proses, tetapi semuanya sudah tidak digunakan lagi.
4. Mengambil ID
Hal utama yang perlu diingat adalah bahwa, di MongoDB, klien menghasilkan pengidentifikasi unik dari Dokumen sebelum dikirim ke cluster. Ini berbeda dengan urutan dalam database relasional. Ini membuat pengambilan ID ini cukup mudah.
4.1. ID yang dibuat oleh pengemudi
Cara standar dan mudah untuk menghasilkan ID unik dari Dokumen adalah dengan membiarkan pengemudi melakukan pekerjaannya. Saat kami menyisipkan Dokumen baru ke Koleksi , jika tidak ada _id bidang ada di Dokumen , driver menghasilkan ObjectId . baru sebelum mengirim perintah insert ke cluster.
Kode kami untuk menyisipkan Dokumen baru ke dalam Koleksi Anda mungkin terlihat seperti ini :
Document document = new Document();
document.put("name", "Shubham");
document.put("company", "Baeldung");
collection.insertOne(document);
Kami dapat melihat bahwa kami tidak pernah menunjukkan bagaimana ID harus dibuat.
Ketika insertOne() metode kembali, kita bisa mendapatkan ObjectId . yang dihasilkan dari Dokumen :
ObjectId objectId = document.getObjectId("_id");
Kami juga dapat mengambil ObjectId seperti bidang standar Dokumen dan kemudian melemparkannya ke ObjectId :
ObjectId oId = (ObjectId) document.get("_id");
4.2. ID Khusus
Cara lain untuk mengambil ID adalah dengan membuatnya dalam kode kita dan memasukkannya ke dalam Dokumen seperti bidang lainnya. Jika kami mengirim Dokumen dengan _id ke driver, itu tidak akan menghasilkan yang baru.
Kami mungkin memerlukan ini dalam beberapa kasus di mana kami memerlukan ID dari Dokumen MongoDB sebelum memasukkan Dokumen di Koleksi .
Kami dapat membuat ObjectId baru dengan membuat instance baru dari kelas :
ObjectId generatedId = new ObjectId();
Atau, kita juga dapat memanggil static get() metode ObjectId kelas:
ObjectId generatedId = ObjectId.get();
Kemudian, kita hanya perlu membuat Dokumen dan gunakan ID yang dihasilkan. Untuk melakukannya, kami dapat menyediakannya di Dokumen konstruktor:
Document document = new Document("_id", generatedId);
Atau, kita dapat menggunakan put() metode:
document.put("_id", generatedId);
Saat menggunakan ID yang dibuat pengguna, kita harus berhati-hati untuk membuat ObjectId baru sebelum setiap penyisipan, karena ID duplikat dilarang. ID duplikat akan menghasilkan MongoWriteException dengan pesan kunci duplikat.
ObjectId class menyediakan beberapa konstruktor lain yang memungkinkan kita untuk mengatur beberapa bagian dari pengidentifikasi:
public ObjectId(final Date date)
public ObjectId(final Date date, final int counter)
public ObjectId(final int timestamp, final int counter)
public ObjectId(final String hexString)
public ObjectId(final byte[] bytes)
public ObjectId(final ByteBuffer buffer)
Namun, kita harus sangat berhati-hati saat menggunakan konstruktor tersebut karena keunikan ID yang diberikan kepada driver bergantung sepenuhnya pada kode kita. Kami bisa mendapatkan kesalahan kunci duplikat dalam kasus khusus ini:
- jika kita menggunakan tanggal yang sama (atau timestamp) &counter combo beberapa kali
- Jika kita menggunakan String heksadesimal yang sama , byte array, atau ByteBuffer beberapa kali