2013-01-12 14 views
20

Io uso mongodb + node.js + mongoose.js ORM backend.Come gestire la modifica dello "schema" mongodb nella produzione

diciamo II hanno qualche array nidificato di oggetti senza campo _id

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

E poi voglio campo annuncio _id a tutti objectds nidificate, quindi lo schema mangusta sarebbe

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

Poi Dovrei eseguire qualche script per modificare il DB di produzione, giusto? Qual è il modo migliore per gestire questo cambiamento? Quale strumento (o approccio) è il migliore da usare per implementare il cambiamento?

+0

Dall'esempio che hai fornito, sembra che tu voglia rimuovere _id, invece di aggiungerlo. Se si desidera aggiungere un _id, come si determina cosa dovrebbe essere ogni _id? – Eduardo

+0

Non ti capisco. _id: false dice a mangusta di non generare _id per gli oggetti descritti da schema, se rimuovo _id: false dalla descrizione dello schema, mangusta creerà nuovi documenti con _id generato. Quello che sto chiedendo è il modo giusto per popolare tutti gli oggetti esistenti (che non hanno _id) con nuovi _id. – WHITECOLOR

+0

dovrebbe _id essere generato dal sistema, o da voi? – Eduardo

risposta

12

Uno dei vantaggi significativi dei database senza schema è che non è necessario aggiornare l'intero database con nuovi layout di schema. Se alcuni dei documenti nel DB non hanno informazioni particolari, allora il tuo codice può fare la cosa appropriata, oppure scegliere di fare ora qualcosa con quel record.

Un'altra opzione è per aggiornare pigramente i documenti come richiesto, solo quando vengono guardati di nuovo. In questo caso, si potrebbe scegliere di avere un flag per versione/documento - che inizialmente potrebbe anche non apparire (e quindi indicare una 'versione 0'). Anche quello è opzionale però. Invece, il tuo codice di accesso al database cerca i dati che richiede e, se non esiste, poiché è una nuova informazione, aggiunta dopo un aggiornamento del codice, riempirebbe i risultati al meglio delle sue capacità.

Per esempio, la conversione di un _id:false in uno standard MongoId campo, quando il codice viene letto (o scritto di nuovo dopo un aggiornamento), e il _id:false è attualmente impostato, quindi fare il cambiamento e scrivere solo quando è assolutamente necessario.

+0

Scusa, non capisco cosa intendi con '_id: false'. Sono davvero interessato Puoi spiegarlo, per favore? – hgoebl

+0

Ah, non ho letto il testo della domanda, mi dispiace, non è colpa tua. Ma l'esempio con '_id: false' potrebbe essere un po 'fuorviante per l'intera domanda. Sarebbe bello avere un esempio che sia meglio comprensibile per tutti e specialmente per quelli che non usano Mongoose. – hgoebl

+1

Come sarà con operazioni come l'aggiunta di un nuovo indice: 'patientSchema.index ({patientId: 1, istituto: 1}, {unique: true})', in dev ho dovuto eliminare il vecchio indice senza '{unique : true} 'per farlo funzionare –

10

Devi scrivere lo script che andrà su una raccolta e aggiungere un nuovo campo a ciascun documento. Tuttavia, il modo esatto con cui lo farai dipende dalla dimensione del tuo DB e dalle prestazioni del tuo sistema di storage. L'aggiunta di un campo al documento cambierà la sua dimensione e quindi causerà il trasferimento nella maggior parte dei casi. Questa operazione ha un impatto su IO e anche limitata da esso. Se la tua collezione è composta da poche migliaia di documenti, potrebbe essere di centomila, quindi puoi semplicemente scorrere su di essa in un ciclo perché l'intera raccolta probabilmente si adatta alla memoria e tutti gli IO succederanno in seguito. Tuttavia, se la raccolta si estende ben oltre la memoria disponibile, l'approccio è più complicato. Noi di solito seguiamo prossimi passi in uso produzione di MongoDB:

  • aperta cursore con timeout = False
  • Leggi un pezzo di documenti in memoria
  • query di aggiornamento Esegui questi documenti
  • sonno per qualche tempo a evitare di sovraccaricare sottosistema IO e ferire un'applicazione di produzione
  • Ripetere fino a cottura
  • chiudere il cursore :)

Le dimensioni del blocco dei documenti e il periodo di sospensione devono essere determinati sperimentalmente. Di solito, si desidera evitare QR/QW nei mongostati per il periodo di migrazione. Per raccolte più ampie su unità lente (come EBS su Amazon) questo approccio IO-safe può richiedere da ore a giorni.

+0

Hai un esempio di codice breve per il cursore? Sono particolarmente interessato alla versione JavaScript, perché penso che non sia banale, specialmente dormendo per un po 'di tempo e non diventando parallelo ... – hgoebl

+0

Non ho un esempio per JavaScript, ma nel driver PyMongo disabilita il timeout per il cursore fatto semplicemente passando timeout = False to find() metodo. Penso che il driver JavaScript avrà qualcosa di simile. –

Problemi correlati