Beberapa hal yang dapat Anda lakukan di sini:
Pertama-tama, gunakan $in alih-alih $or.
Kedua, MongoDB hanya gunakan indeks untuk kecocokan pertama Anda, jadi Anda harus memutuskan (dengan mencobanya) mana dari dua kecocokan yang lebih baik. Tujuannya adalah untuk mendapatkan kueri secepat mungkin, dan lebih sedikit dokumen yang melalui saluran Anda. Untuk itu lakukan hal-hal berikut:
Pertama, buat tiga indeks:
db.element.ensureIndex( { 'versions.branch' : 1 } );
db.element.ensureIndex( { 'doctype' : 1 } );
db.element.ensureIndex( { 'prefix' : 1 } );
Kemudian jalankan tiga kueri berikut dan perhatikan bidang "kursor", "n", "nScanned" dan "ms":
branch = "nameofbranch"; // guessing here
db.element.find( "versions.branch": branch ).explain();
db.element.find( "doctype" { $in: [ "15281", "15282" .... ] } ).explain();
db.element.find( "prefix": { $ne: "500" } ).explain();
Untuk kueri terakhir, Anda akan mencatat bahwa "kursor" adalah "BasicCursor", karena kueri $ne tidak dapat menggunakan indeks.
Dua lainnya akan menunjukkan kepada Anda berbagai nilai untuk "ms", "n" dan "nScanned". "ms" adalah waktu yang diperlukan untuk menjalankan kueri. Jika ini kira-kira sama, lihat perbedaan antara nilai "n" dan "nScanned". Saya akan mengharapkan dan menebak bahwa perbedaan untuk kueri "versions.branch" adalah 0. Untuk kueri "doctype" mungkin berbeda. Jika "ms" tidak kira-kira sama, masukkan $match yang merupakan yang tercepat pertama sebagai klausa $match di saluran agregasi Anda.
Jika kecepatan ("ms") keduanya sama, periksa nilai "n". Jika "n" untuk kueri "awalan" adalah "5" dan "n" untuk kueri "versions.branch" adalah "500" maka itu berarti hasil kueri "awalan" lebih baik, karena lebih sedikit dokumen dikembalikan. Dalam hal ini, masukkan itu sebagai klausa $match pertama Anda secara agregat. Jika "versions.branch" jauh lebih sedikit, gunakan yang itu sebagai klausa $match pertama.