2013-01-11 8 views
21

Szybko rozwijamy aplikację, która używa Mongoose, a nasze schematy często się zmieniają. Nie potrafię wymyślić właściwego sposobu aktualizowania schematu dla istniejących dokumentów, bez zdmuchiwania ich i ponownego odtwarzania ich od zera.Zmiana formatu schematu Mangowego

Natknąłem się na http://mongoosejs.com/docs/api.html#schema_Schema-add, który wygląda na prawidłowy. Nie ma prawie żadnej dokumentacji na temat tego, jak właściwie to zaimplementować, co jest bardzo trudne dla kogoś, kto jest nowy w MongoDB.

Po prostu chcę dodać nowe pole o nazwie włączone. Moja definicja schematu to:

var sweepstakesSchema = new Schema({ 
    client_id: { 
     type: Schema.Types.ObjectId, 
     ref: 'Client', 
     index: true 
    }, 
    name: { 
     type: String, 
     default: 'Sweepstakes', 
    }, 
    design: { 
     images: { 
      type: [], 
      default: [] 
     }, 
     elements: { 
      type: [], 
      default: [] 
     } 
    }, 
    enabled: { 
     type: Boolean, 
     default: false 
    }, 
    schedule: { 
     start: { 
      type: Date, 
      default: Date.now 
     }, 
     end: { 
      type: Date, 
      default: Date.now 
     } 
    }, 
    submissions: { 
     type: Number, 
     default: 0 
    } 
}); 

Odpowiedz

10

Nic nie jest wbudowane w Mongoose w odniesieniu do migracji istniejących dokumentów w celu dostosowania do zmiany schematu. Musisz to zrobić w swoim własnym kodzie, w razie potrzeby. W przypadku, takim jak nowe pole enabled, prawdopodobnie najczystsze jest pisanie kodu, aby traktować brakujące pole enabled, tak jakby było ustawione na false, więc nie trzeba dotykać istniejących dokumentów.

Jeśli chodzi o sam schemat, po prostu zaktualizuj swoją definicję Schema, tak jak to pokazano, ale zmiany takie jak nowe pola z wartościami default wpłyną tylko na nowe dokumenty.

+0

* ale zmiany, takie jak nowe pola z wartościami domyślnymi, wpłyną tylko na nowe dokumenty w przyszłości. * - Sądzę, że ma to również wpływ na zaktualizowane dokumenty, prawda? (nie tylko nowy) – Michael

+0

@Michael Nie, nie. Dodanie nowych pól z wartością domyślną sprawi, że te pola pojawią się w mongoose wystąpień istniejących dokumentów, ale w rzeczywistości nie doda to pola do istniejących dokumentów, nawet jeśli wywołasz na nich "zapisz". – JohnnyHK

+0

Zatem zapisanie dokumentu, który poprzednio nie miał pola 'x' po dodaniu' x' do schematu z wartością domyślną, nie aktualizuje dokumentu z 'x'? Nie rozumiem tego wyboru projektu, czy jest to gdzieś udokumentowane? Dzięki – Michael

1

Szukałem również czegoś w rodzaju migracji, ale go nie znalazłem. Alternatywnie możesz użyć wartości domyślnych. Jeśli klucz ma wartość domyślną, a klucz nie istnieje, użyje wartości domyślnej.

Mongoose Defaults

wartości domyślne zastosowano gdy szkielet dokument jest wykonana. Oznacza to, że jeśli utworzysz nowy dokument (nowy MyModel) lub znajdziesz istniejący dokument (MyModel.findById), oba będą miały ustawienia domyślne pod warunkiem, że brakuje określonego klucza.

5
db.sweepstakesModel.find({ enabled : { $exists : false } }).forEach(
    function (doc) { 
     doc.enabled = false; 
     db.sweepstakesModel.save(doc); 
    } 
) 

rozważa swoją Mongoose nazwę modelu jako „sweepstakesModel”, Ten kod będzie dodać „Enabled” pole z wartością logiczną „false” do wszystkich wcześniej istniejących dokumentów w kolekcji.

+0

Chociaż może to teoretycznie odpowiedzieć na pytanie, [byłoby lepiej] (// meta.stackoverflow.com/q/8259), aby uwzględnić istotne części odpowiedzi tutaj, i podać link dla odniesienia. –

+0

@bhargav, zaktualizowałem swoją odpowiedź poprawnym kodem mangusty. Spróbuj. Kod działa dobrze dla mnie – Vickar

+0

Dzięki za to. –

Powiązane problemy