Rimuovi un campo da tutti gli elementi dell’array in mongodb

Ho sotto documento in MongoDB (2.4.5)

{ "_id" : 235399, "casts" : { "crew" : [ { "_id" : 1186343, "withBase" : true, "department" : "Directing", "job" : "Director", "name" : "Connie Rasinski" }, { "_id" : 86342, "withBase" : true } ] }, "likes" : 0, "rating" : 0, "rating_count" : 0, "release_date" : "1955-11-11" } 

Voglio rimuovere con Base file dagli elementi di array all’interno di casts.crew ..

Ho provato questo

 db.coll.update({_id:235399},{$unset: { "casts.crew.withBase" : 1 } },false,true) 

niente è cambiato.

E provato questo ..

 db.coll.update({_id:235399},{$unset: { "casts.crew" : { $elemMatch: { "withBase": 1 } } } },false,true) 

rimosse l’intera schiera di equipaggi dal documento.

Qualcuno può fornirmi la richiesta giusta?

Mi dispiace deluderti, ma la tua risposta

 db.coll.update({ _id:235399, "casts.crew.withBase": {$exists: true} },{ $unset: { "casts.crew.$.withBase" : true } },false,true) 

non è corretto. In realtà rimuoverà il valore, MA solo dalla prima occorrenza del documento secondario, a causa del modo in cui l’ operatore posizionale funziona :

l’operatore $ posizionale funge da segnaposto per il primo elemento che corrisponde al documento della query

Inoltre non puoi usare $unset (come hai provato prima) perché non può funzionare sugli array (e stai sostanzialmente cercando di rimuovere una chiave da un documento dall’array). Non puoi anche rimuoverlo con $pull , perché pull rimuove tutto l’array, non solo un campo di esso.

Quindi per quanto ne so non puoi farlo con un semplice operatore. Quindi l’ultima risorsa sta facendo $find e poi forEach con save. Puoi vedere come farlo nella mia risposta qui . Nel tuo caso hai bisogno di avere un altro ciclo in funzione ” forEach per scorrere l’array e cancellare un tasto . Spero che tu possa modificarlo. Se no, cercherò di aiutarti.

PS Se qualcuno guarda un modo per farlo – ecco la funzione di Sandra

 db.coll.find({_id:235399}).forEach( function(doc) { var arr = doc.casts.crew; var length = arr.length; for (var i = 0; i < length; i++) { delete arr[i]["withBase"]; } db.coll.save(doc); }); 

È ansible utilizzare il nuovo positional identifier per aggiornare più elementi dell’array in 3.6.

Qualcosa di simile a

  db.coll.update( {_id:235399}, {$unset: {"casts.crew.$[].withBase":""}} ) 

$ [] rimuove tutte le proprietà withBase dall’array crews . Agisce come segnaposto per l’aggiornamento di tutti gli elementi dell’array.

Usa multi true per influenzare più documenti.

Ho trovato un modo per disinserire questo elenco senza dover sollevare l’object (cioè, semplicemente facendo un aggiornamento), è un po ‘schifoso ma se si dispone di un enorme database farà l’affare:

 db.coll.update({},{$unset: {"casts.crew.0.withBase" : 1, "casts.crew.1.withBase" : 1} }, {multi: 1}) 

In altre parole, devi calcolare quanti oggetti ci possono essere in qualsiasi tuo elenco di documenti e aggiungere questi numeri esplicitamente, in questo caso come {casts.crew.NUMBER.withBase: 1} .

Inoltre, per contare l’array più lungo in un object mongodb, si può fare un aggregato, qualcosa del genere:

 db.coll.aggregate( [ { $unwind : "$casts.crew" }, { $group : { _id : "$_id", len : { $sum : 1 } } }, { $sort : { len : -1 } }, { $limit : 1 } ], {allowDiskUse: true} ) 

Voglio solo sottolineare che questa non è una soluzione carina ma è molto più veloce del recupero e del recupero.