Kunci utama MongoDB adalah teman Anda

Semua dokumen dalam koleksi MongoDB memiliki sulih suara kunci utama _id. Bidang ini secara otomatis ditetapkan ke dokumen saat disisipkan, jadi jarang ada kebutuhan untuk menyediakannya. Yang menarik dari _idbidang ini adalah bahwa ini berbasis waktu . Artinya, jenis yang mendasari _id, yaitu ObjectId, jenis BSON 12-byte, dan 4 dari byte tersebut mewakili detik sejak zaman Unix.

Yang juga istimewa tentang _idbidang ini adalah bidang ini otomatis diindeks seperti yang Anda lihat di bawah ini dengan memanggil getIndexeskoleksi apa pun.

1 2 3 4 5 6 7 8 9 10 11 
> db.things.getIndexes() [ { "v" : 1, "key" : { "_id" : 1 }, "ns" : "test.things", "name" : "_id_" } ] 

Dan seperti yang diingat semua orang dari RDBMS tradisional, indeks penting karena mereka dapat membuat pengambilan dokumen lebih cepat; meskipun demikian, indeks memang menggunakan memori dan ada sedikit hukuman kinerja saat memasukkan dokumen karena semua indeks yang sesuai harus diperbarui. Jadi, meskipun Anda harus mempertimbangkan dengan serius menggunakan indeks, Anda harus hemat dalam penggunaannya.

Biasanya, mencari berdasarkan dokumen _idhanya nyaman jika Anda mengetahuinya . Lebih sering daripada tidak, dokumen dicari melalui bidang lain dan jika Anda menemukan diri Anda mencari melalui deret waktu, seperti created_atmaka Anda sedang dalam perawatan.

Bayangkan sebuah koleksi logsyang berisi dokumen sederhana yang menangkap berbagai pesan log. Contoh dokumen bisa terlihat seperti ini:

1 2 3 4 5 6 
{ "_id" : ObjectId("51c4ab6d4d6906d494460728"), "message" : "crashed, no such method exception", "type" : "crash", "created_at" : ISODate("2013-06-21T19:37:17.992Z") } 

Bagaimana jika saya ingin menemukan semua pesan log untuk beberapa tanggal, seperti hari ini? Saya bisa menulis kueri saya seperti ini:

1 
db.logs.find({created_at:{'$gt': new Date(2013, 5, 20)}}) 

Jika saya melempar penjelasan ke kueri itu, saya dapat melihat itu karena saya tidak memiliki indeks created_at, kursor dasar dimanfaatkan dan semua dokumen dalam koleksi dipindai untuk mengambil hasil saya.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 
> db.logs.find({created_at:{'$gt': new Date(2013, 5, 20)}}).explain() { "cursor" : "BasicCursor", "isMultiKey" : false, "n" : 2, "nscannedObjects" : 4, "nscanned" : 4, "nscannedObjectsAllPlans" : 4, "nscannedAllPlans" : 4, "scanAndOrder" : false, "indexOnly" : false, "nYields" : 0, "nChunkSkips" : 0, "millis" : 0, "indexBounds" : { }, "server" : "ghome-computer.home:27017" } 

Seperti yang Anda lihat, menelusuri melalui created_atlapangan bisa jadi tidak efisien; dengan demikian, Anda mungkin tergoda untuk melempar indeks pada bidang itu. Ini secara alami akan membuat kueri tersebut lebih efisien, namun, Anda akan dikenai biaya indeks baru yang menghabiskan lebih banyak memori dan penyisipan akan sedikit lebih lambat karena pembaruan ke indeks yang baru dibuat tersebut.

Ternyata, karena _idbidang tersebut menyematkan epoch Unix di dalamnya, Anda dapat dengan mudah membuat ekspresi find tanpa menyertakan created_atbidang tersebut. Misalnya, driver MongoDB Ruby memungkinkan Anda membuat ObjectIddari Timeseperti ini: