Po pierwsze, zastanówmy się, co GridFS właściwie jest. Na początek zapoznajmy się ze stroną podręcznika, do której się odnosi:
Więc pozbądź się tego i to może być twój przypadek użycia. Ale lekcja, której należy się tutaj nauczyć, jest taka, że GridFS nie jest automatycznie metoda "idź do" do przechowywania plików.
To, co wydarzyło się tutaj w Twoim przypadku (i innych), wynika z specyfikacji poziomu kierowcy że tak jest (a sama MongoDB robi nie magia tutaj), Twoje „pliki” zostały „podzielone” na dwie kolekcje. Jedna kolekcja dla głównego odniesienia do treści, a druga dla „kawałków” danych.
Twoim problemem (i innymi) jest to, że udało Ci się zostawić „kawałki” teraz, gdy „główne” odniesienie zostało usunięte. Więc z dużą liczbą, jak pozbyć się sierot.
Twój obecny odczyt mówi „zapętl i porównaj”, a ponieważ MongoDB nie wykonuje łączeń , to naprawdę nie ma innej odpowiedzi. Ale jest kilka rzeczy, które mogą pomóc.
Więc zamiast uruchamiać ogromny $nin
, spróbuj zrobić kilka różnych rzeczy, aby to przerwać. Rozważ pracę w odwrotnej kolejności, na przykład:
db.fs.chunks.aggregate([
{ "$group": { "_id": "$files_id" } },
{ "$limit": 5000 }
])
Więc to, co tam robisz, to wyraźne Wartości "files_id" (będące odniesieniami do fs.files
), ze wszystkich wpisów, na 5000 wpisów na początek. Potem oczywiście wracasz do pętli, sprawdzając fs.files
dla pasującego _id
. Jeśli czegoś nie znajdziesz, usuń dokumenty pasujące do „files_id” z Twoich „fragmentów”.
Ale to było tylko 5000, więc zachowaj ostatni id został znaleziony w tym zestawie, ponieważ teraz ponownie uruchomisz tę samą instrukcję zbiorczą, ale w inny sposób:
db.fs.chunks.aggregate([
{ "$match": { "files_id": { "$gte": last_id } } },
{ "$group": { "_id": "$files_id" } },
{ "$limit": 5000 }
])
Więc to działa ponieważ ObjectId
wartości to monotoniczne
lub „stale rosnący”. Więc wszystkie nowe wpisy są zawsze większe niż ostatni. Następnie możesz ponownie zapętlić te wartości i wykonać to samo usuwanie, jeśli nie zostały znalezione.
Czy to „potrwa wiecznie”. Cóż tak . możesz zatrudnij db.eval()
w tym celu, ale przeczytaj dokumentacja. Ale ogólnie jest to cena, jaką płacisz za używanie dwóch kolekcje.
Wróć do początku. GridFS specyfikacja jest zaprojektowana w ten sposób, ponieważ szczególnie chce obejść ograniczenie 16 MB. Ale jeśli to nie Twoje ograniczenia, a następnie zapytaj dlaczego używasz GridFS przede wszystkim.
MongoDB nie ma problemu przechowywanie danych „binarnych” w dowolnym elemencie danego dokumentu BSON. Więc nie potrzebujesz używać GridFS tylko do przechowywania plików. A jeśli to zrobiłeś, to wszystkie Twoich aktualizacji byłoby całkowicie „atomowych”, ponieważ działają tylko na jednym dokument w jednym odbiór na raz.
Od GridFS
celowo dzieli dokumenty na kolekcje, a jeśli go używasz, to żyjesz z bólem. Więc użyj go, jeśli potrzebujesz to, ale jeśli nie , a następnie po prostu zapisz BinData
jako normalne pole, a te problemy znikają.
Ale przynajmniej masz lepsze podejście niż ładowanie wszystkiego do pamięci.