2012-03-13 10 views
7

Ho un database di documenti personali. Ognuno ha un campo chiamato foto, che è una serie di documenti fotografici. Vorrei aggiungere un nuovo flag "revisionato" a ciascuno dei documenti fotografici e inizializzarlo su false.Aggiungere un nuovo campo a tutti i documenti in un array nidificato

Questa è la domanda che sto cercando di utilizzare:

db.person.update({ "_id" : { $exists : true } }, {$set : {photos.reviewed : false} }, false, true) 

Tuttavia ottengo il seguente errore:

SyntaxError: missing : after property id (shell):1 

questo è possibile, e se sì, che cosa faccio di sbagliato nel mio aggiornare?

Ecco un esempio completo della 'persona' documento:

{ 
"_class" : "com.foo.Person", 
"_id" : "2894", 
"name" : "Pixel Spacebag", 
"photos" : [ 
    { 
     "_id" : null, 
     "thumbUrl" : "http://site.com/a_s.jpg", 
     "fullUrl" : "http://site.com/a.jpg" 
    }, 
    { 
     "_id" : null, 
     "thumbUrl" : "http://site.com/b_s.jpg", 
     "fullUrl" : "http://site.com/b.jpg" 
    }] 
} 

Bonus karma per chi mi può dire un detergente per cui per aggiornare "tutti i documenti" senza utilizzare la query { "_id" : { $exists : true } }

risposta

9

Is this possible, and if so, what am I doing wrong in my update?

No. In generale MongoDB è solo bravo a fare aggiornamenti sugli oggetti di livello superiore.

L'eccezione qui è $ positional operator. Dai documenti: Use this to find an array member and then manipulate it.

Tuttavia, nel tuo caso si desidera modificare tutti i membri in un array. Quindi non è quello che ti serve.

Bonus karma for anyone who can tell me a cleaner why to update "all documents"

Provare db.coll.update(query, update, false, true), questo emetterà un aggiornamento "multi". Quest'ultimo true è ciò che lo rende un multi.

Is this possible,

Hai due opzioni qui:

  1. scrivere un ciclo for per eseguire l'aggiornamento. Sarà fondamentalmente un ciclo nidificato for, uno per scorrere i dati, l'altro per scorrere attraverso l'array secondario. Se si dispone di molti dati, si consiglia di scrivere questo è il driver di scelta (e possibilmente multi-thread è).
  2. Scrivi il tuo codice per gestire reviewed come annullabile. Scrivi i dati in modo che se viene visualizzata una foto con reviewed indefinita, deve essere false. Quindi è possibile impostare il campo in modo appropriato e ripristinarlo nel DB.

Metodo # 2 è qualcosa che si dovrebbe abituare. Man mano che i tuoi dati crescono e aggiungi campi, diventa difficile "backportare" tutti i vecchi dati. Questo è simile al problema dell'emissione di una modifica dello schema in SQL quando si hanno elementi 1B nel DB.

Invece basta rendere il codice resistente allo null e imparare a considerarlo come predefinito.

Ancora una volta, questa non è ancora la soluzione che cerchi.

+0

Buona risposta. Per chiarire quello che stavo cercando per il "bonus" era un modo per aggiornare tutti i documenti con una query "semplice" (qualcosa di più semplice di "{" _id ": {$ exists: true}}". Capisco il "multi" "param, ma ho ancora bisogno di una query che corrisponda a tutti i documenti. Ho pensato che forse" {} "corrisponderebbe a tutti i documenti, ma io non la penso così? –

+0

E no, questa non è una" soluzione ", ma è una buona spiegazione del motivo per cui semplicemente non riesco a ottenere ciò che sto cercando con la versione curata di mongodb (2.0.2) .Se una soluzione diventa disponibile, si prega di inviare un'altra risposta per gli utenti futuri .. –

-1

È possibile farlo

(null, {$set : {"photos.reviewed" : false} }, false, true) 

Il primo parametro è nullo: nessuna specifica = qualsiasi elemento della collezione.

"photos.reviewed" deve essere dichiarato come stringa per aggiornare il sottocampo.

+2

non è possibile farlo. con 'assert fallito: serve una query' – Warz

-1

Si può fare in questo modo:

db.person.update({}, $set:{name.surname:null}, false, true); 
-1

argomento vecchio ora, ma questo solo ha lavorato bene con Mongo 3.0.6:

db.users.update({ _id: ObjectId("55e8969119cee85d216211fb") }, { $set: {"settings.pieces": "merida"} })

Nel mio caso un'entità utente si presenta come

{ _id: 32, name: "foo", ..., settings: { ..., pieces: "merida", ...} } 
+0

Non hai un array, come nella domanda. – Gramic

Problemi correlati