Pertama, mari luangkan waktu untuk mempertimbangkan apa GridFS sebenarnya adalah. Dan sebagai permulaan, mari kita baca dari halaman manual yang dirujuk:
Jadi dengan itu, dan itu mungkin kasus penggunaan Anda. Tapi pelajaran untuk dipelajari di sini adalah bahwa GridFS tidak secara otomatis metode "masuk" untuk menyimpan file.
Apa yang terjadi di sini dalam kasus Anda (dan lainnya) adalah karena spesifikasi tingkat pengemudi" bahwa ini (dan MongoDB sendiri tidak tidak ajaib di sini), "File" Anda telah "dibagi" menjadi dua koleksi. Satu koleksi untuk referensi utama konten, dan koleksi lainnya untuk "potongan" data.
Masalah Anda (dan lainnya), adalah Anda telah berhasil meninggalkan "potongan" sekarang setelah referensi "utama" telah dihapus. Jadi dengan jumlah yang banyak, bagaimana cara menyingkir dari anak yatim.
Bacaan Anda saat ini mengatakan "putar dan bandingkan", dan karena MongoDB tidak bergabung , maka benar-benar tidak ada jawaban lain. Tapi ada beberapa hal yang bisa membantu.
Jadi daripada menjalankan $nin
huge yang besar , coba lakukan beberapa hal berbeda untuk memecahnya. Pertimbangkan untuk mengerjakan urutan terbalik, misalnya:
db.fs.chunks.aggregate([
{ "$group": { "_id": "$files_id" } },
{ "$limit": 5000 }
])
Jadi apa yang Anda lakukan di sana adalah mendapatkan berbeda nilai "files_id" (menjadi referensi ke fs.files
), dari semua entri, untuk 5000 entri Anda untuk memulai. Kemudian tentu saja Anda kembali ke perulangan, memeriksa fs.files
untuk _id
matching yang cocok . Jika sesuatu tidak ditemukan, maka hapus dokumen yang cocok dengan "files_id" dari "potongan" Anda.
Tapi itu hanya 5.000, jadi pertahankan terakhir id ditemukan di set itu, karena sekarang Anda akan menjalankan pernyataan agregat yang sama lagi, tetapi berbeda:
db.fs.chunks.aggregate([
{ "$match": { "files_id": { "$gte": last_id } } },
{ "$group": { "_id": "$files_id" } },
{ "$limit": 5000 }
])
Jadi ini berhasil karena ObjectId
nilainya monotonik
atau "semakin meningkat". Jadi semuanya baru entri selalu lebih besar dari yang terakhir. Kemudian Anda dapat mengulang nilai tersebut lagi dan melakukan penghapusan yang sama jika tidak ditemukan.
Akankah ini "mengambil selamanya". Yah ya . Anda mungkin gunakan db.eval()
untuk ini, tetapi baca dokumentasi. Namun secara keseluruhan, ini adalah harga yang Anda bayar untuk menggunakan dua koleksi.
Kembali ke awal. GridFS spesifikasi dirancang cara ini karena secara khusus ingin mengatasi keterbatasan 16MB. Tetapi jika itu tidak keterbatasan Anda, lalu pertanyakan mengapa anda menggunakan GridFS di tempat pertama.
MongoDB tidak ada masalah menyimpan data "biner" dalam elemen apa pun dari dokumen BSON tertentu. Jadi Anda tidak perlu untuk menggunakan GridFS hanya untuk menyimpan file. Dan jika Anda telah melakukannya, maka semua pembaruan Anda akan sepenuhnya "atomik", karena hanya bekerja pada satu dokumen dalam satu koleksi sekaligus.
Sejak GridFS
sengaja membagi dokumen di seluruh koleksi, maka jika Anda menggunakannya, maka Anda hidup dengan rasa sakit. Jadi gunakan jika Anda membutuhkan itu, tetapi jika Anda tidak , lalu simpan saja BinData
sebagai bidang normal, dan masalah ini hilang.
Tapi setidaknya Anda memiliki pendekatan yang lebih baik untuk diambil daripada memuat semuanya ke dalam memori.