2013-01-12 9 views
20

Używam mondomb + node.js + backend ORM mongoose.js.Jak radzić sobie z mongotb "schematu" zmiana w produkcji

powiedzmy II jakieś zagnieżdżony tablicę obiektu bez pola _id

mongoose.Schema({ 
    nested: [{ 
    _id: false, prop: 'string' 
    }] 
}) 

A potem chcę pola _id ogłoszenie do wszystkich zagnieżdżonych objectds, więc schemat mangusta byłoby

mongoose.Schema({ 
    nested: [{ 
    prop: 'string' 
    }] 
}) 

Następnie Powinienem uruchomić skrypt, aby zmodyfikować DB produkcji, prawda? Jaki jest najlepszy sposób na obsługę takich zmian? Które narzędzie (lub podejście) najlepiej zastosować do wdrożenia zmiany?

+0

Z podanego przykładu wygląda na to, że chcesz usunąć _id zamiast go dodawać. Jeśli chcesz dodać _id, jak ustalić, jaki powinien być każdy _id? – Eduardo

+0

Nie rozumiem. _id: false mówi mangusty, aby nie generować _id dla obiektów opisanych przez schematu, jeśli usunąć _id false z opisu schematu mangusta stworzy nowe dokumenty z wygenerowanym _id. To, o co pytam, to właściwy sposób wypełniania wszystkich istniejących obiektów (które nie mają _id) nowymi _ids. – WHITECOLOR

+0

czy _ids powinny być generowane przez system, czy przez ciebie? – Eduardo

Odpowiedz

12

Jedną ze znaczących zalet baz danych bez schematów jest to, że nie trzeba aktualizować całej bazy danych za pomocą nowych schematów schematów. Jeśli niektóre dokumenty w DB nie mają konkretnych informacji, twój kod może zamiast tego zrobić odpowiednią rzecz lub zdecydować się na zrobienie czegokolwiek z tym rekordem.

Inną opcją jest leniwie aktualizować dokumentów zgodnie z wymaganiami - tylko wtedy, gdy są ponownie przeglądane. W tym przypadku możesz zdecydować się na flagę wersji na jeden rekord/wersję dokumentu - która początkowo może się nawet nie pojawić (i tym samym oznaczać "wersję 0"). Nawet to jest opcjonalne. Zamiast tego twój kod dostępu do bazy danych wyszukuje potrzebne dane, a jeśli nie istnieje, ponieważ jest to nowa informacja, dodana po aktualizacji kodu, to wypełni wyniki w najlepszy możliwy sposób.

Dla przykładu, przekształcenie _id:false do standardowego MongoId pola, gdy kod jest odczytywany (lub pisemnej z powrotem po aktualizacji), a _id:false jest aktualnie ustawiony, a następnie dokonać zmian i zapisać go tylko wtedy, gdy jest to absolutnie wymagany.

+0

Przepraszam, nie rozumiem, co masz na myśli z '_id: false'. Jestem naprawdę zainteresowany. Czy możesz to wyjaśnić? – hgoebl

+0

Ach, ja nie czytałem tekst pytania, przepraszam, to nie twoja wina. Ale przykład z '_id: false' może być trochę mylący dla całego pytania. Byłoby miło mieć przykład, który jest lepiej zrozumiały dla wszystkich, a zwłaszcza dla tych, którzy nie używają Mongoose. – hgoebl

+1

Jak to będzie z operacji, jak dodawanie nowego indeksu: 'patientSchema.index ({ID_Pacjenta: 1, instytut: 1}, {wyjątkowy: true})' w dev musiałem usunąć stary indeks bez '{wyjątkowy : true} ', aby działało –

10

Rzeczywiście, musisz napisać skrypt, który przejdzie do kolekcji i dodać nowe pole do każdego dokumentu. Dokładny sposób, w jaki to zrobisz, zależy jednak od rozmiaru bazy danych i wydajności twojego systemu pamięci masowej. Dodanie pola do dokumentu zmieni jego rozmiar, a zatem spowoduje przeniesienie w większości przypadków. Ta operacja ma wpływ na IO, a także jest przez nią ograniczona. Jeśli twoja kolekcja to tylko kilka tysięcy dokumentów, może być nawet sto tysięcy, możesz po prostu powtórzyć ją w jednej pętli, ponieważ cała kolekcja prawdopodobnie pasuje do pamięci i wszystko IO stanie się później. Jeśli jednak zbiór wykracza znacznie poza dostępną pamięć, podejście jest bardziej skomplikowane. Zwykle wykonaj następujące kroki w użytku produkcyjnego MongoDB:

  • Otwórz kursora z Timeout = False
  • Czytaj kawałek dokumentów do pamięci
  • zapytań aktualizacji Run na tych dokumentach
  • uśpienia przez pewien czas uniknąć przeciążenia IO podsystem i rani aplikacja produkcja
  • powtarzać aż zrobione
  • Zamknij kursor :)

Rozmiar dokumentów porcji i okresu spania należy określić eksperymentalnie. Zwykle chcesz uniknąć QR/QW w mongostatach na okres migracji. W przypadku większych kolekcji na wolniejszych dyskach (takich jak EBS na Amazon) to podejście bezpieczne dla IO może trwać od kilku godzin do kilku dni.

+0

Czy masz krótki przykład kodu dla kursora? Jestem szczególnie zainteresowany w wersji JavaScriptu, bo myślę, że to nie jest trywialne, zwłaszcza śpi na jakiś czas, a nie coraz równolegle ... – hgoebl

+0

nie mam przykład dla JavaScriptu, ale w sterowniku PyMongo wyłączenie limitu czasu dla kursora po prostu przechodząc wykonanej przez timeout = Fałsz, aby znaleźć() metodę. Myślę, że sterownik JavaScript będzie miał coś takiego. –

Powiązane problemy