Trước tiên, hãy dành thời gian xem xét GridFS là gì? thực ra Là. Và với tư cách là người mới bắt đầu, hãy đọc từ trang hướng dẫn sử dụng được tham chiếu:
Vì vậy, với điều đó không xảy ra, và đó cũng có thể là trường hợp sử dụng của bạn. Nhưng bài học rút ra ở đây là GridFS không phải là tự động phương pháp "go-to" để lưu trữ tệp.
Điều đã xảy ra ở đây trong trường hợp của bạn (và những trường hợp khác) là do đặc điểm kỹ thuật "cấp trình điều khiển" rằng đây là (và bản thân MongoDB không ma thuật ở đây), "tệp" của bạn đã được "tách" thành hai bộ sưu tập. Một tập hợp cho tham chiếu chính đến nội dung và tập hợp kia cho "các phần" dữ liệu.
Vấn đề của bạn (và những người khác), là bạn đã quản lý để bỏ lại "phần" bây giờ tham chiếu "chính" đã bị xóa. Vậy với một số lượng lớn, làm thế nào để thoát khỏi những đứa trẻ mồ côi.
Bài đọc hiện tại của bạn cho biết "lặp lại và so sánh" và vì MongoDB không tham gia , thì thực sự không có câu trả lời nào khác. Nhưng có một số điều có thể hữu ích.
Vì vậy, thay vì chạy một $nin
khổng lồ , hãy thử làm một vài điều khác nhau để phá vỡ điều này. Hãy xem xét làm việc theo thứ tự ngược lại, ví dụ:
db.fs.chunks.aggregate([
{ "$group": { "_id": "$files_id" } },
{ "$limit": 5000 }
])
Vì vậy, những gì bạn đang làm ở đó là nhận được sự khác biệt giá trị "files_id" (là tham chiếu đến fs.files
), từ tất cả các mục nhập, bắt đầu cho 5000 mục nhập của bạn. Sau đó, tất nhiên bạn quay lại vòng lặp, kiểm tra fs.files
cho một _id
phù hợp . Nếu không tìm thấy thứ gì đó, thì hãy xóa các tài liệu khớp với "files_id" từ "chunks" của bạn.
Nhưng đó chỉ là 5000, vì vậy hãy giữ nguyên cuối cùng id được tìm thấy trong tập hợp đó, bởi vì bây giờ bạn sẽ chạy lại cùng một câu lệnh tổng hợp, nhưng khác:
db.fs.chunks.aggregate([
{ "$match": { "files_id": { "$gte": last_id } } },
{ "$group": { "_id": "$files_id" } },
{ "$limit": 5000 }
])
Vì vậy, điều này hoạt động vì ObjectId
giá trị là monotonic
hoặc "ngày càng tăng". Vì vậy, tất cả mới các mục nhập luôn lớn hơn cuối cùng. Sau đó, bạn có thể lặp lại các giá trị đó và thực hiện thao tác xóa tương tự ở những nơi không tìm thấy.
Điều này sẽ "mất mãi mãi". Chà vâng . Bạn có thể tuyển dụng db.eval()
cho điều này, nhưng đọc tài liệu. Nhưng nhìn chung, đây là cái giá bạn phải trả cho việc sử dụng hai bộ sưu tập.
Trở về vạch xuất phát. GridFS thông số kỹ thuật được thiết kế theo cách này vì nó đặc biệt muốn làm việc xung quanh giới hạn 16MB. Nhưng nếu điều đó không hạn chế của bạn, sau đó đặt câu hỏi tại sao bạn đang sử dụng GridFS ngay từ đầu.
MongoDB không có vấn đề gì lưu trữ dữ liệu "nhị phân" trong bất kỳ phần tử nào của tài liệu BSON nhất định. Vì vậy, bạn không cần để sử dụng GridFS chỉ để lưu trữ các tệp. Và nếu bạn đã làm như vậy, thì tất cả trong số các bản cập nhật của bạn sẽ hoàn toàn là "nguyên tử", vì chúng chỉ hoạt động trên một tài liệu trong một bộ sưu tập tại một thời điểm.
Vì GridFS
cố ý chia nhỏ tài liệu thành các bộ sưu tập, sau đó nếu bạn sử dụng nó, thì bạn phải sống chung với nỗi đau. Vì vậy, hãy sử dụng nó nếu bạn cần nó, nhưng nếu bạn không , sau đó chỉ cần lưu trữ BinData
như một trường bình thường và những vấn đề này sẽ biến mất.
Nhưng ít nhất bạn có một cách tiếp cận tốt hơn là tải mọi thứ vào bộ nhớ.