J'ai ci-dessous le document dans 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"
}
Je veux supprimer withBase déposé des éléments du tableau à l'intérieur de casts.crew ..
J'ai essayé
db.coll.update({_id:235399},{$unset: { "casts.crew.withBase" : 1 } },false,true)
rien n'a changé.
Et j'ai essayé ça ..
db.coll.update({_id:235399},{$unset: { "casts.crew" : { $elemMatch: { "withBase": 1 } } } },false,true)
il a supprimé tout le tableau d'équipage du document.
Quelqu'un peut-il me fournir la bonne requête?
Désolé de vous décevoir, mais votre réponse
db.coll.update({
_id:235399,
"casts.crew.withBase": {$exists: true}
},{
$unset: {
"casts.crew.$.withBase" : true
}
},false,true)
n'est pas correcte. En fait, cela supprimera la valeur, MAIS uniquement à partir de la première occurrence du sous-document, en raison de la façon dont l'opérateur positionnel fonctionne :
l'opérateur positionnel $ agit comme un espace réservé pour le premier élément qui correspond au document de requête
Vous ne pouvez pas non plus utiliser $unset
(comme vous l'avez essayé auparavant) car cela ne peut pas fonctionner sur les tableaux (et essayez-vous essentiellement de supprimer une clé d'un document du tableau). Vous ne pouvez pas non plus le supprimer avec $pull
, car pull supprime tout le tableau, pas seulement un champ de celui-ci.
Par conséquent, pour autant que je sache, vous ne pouvez pas le faire avec un simple opérateur. Donc, le dernier recours fait $find
puis forEach
avec sauvegarde. Vous pouvez voir comment faire cela dans ma réponse ici . Dans votre cas, vous devez avoir une autre boucle dans la fonction forEach
pour parcourir le tableau et supprimer une clé . J'espère que vous pourrez le modifier. Sinon, je vais essayer de vous aider.
P.S. Si quelqu'un cherche un moyen de le faire - voici la fonction de 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);
});
Vous pouvez utiliser le nouveau positional identifier
pour mettre à jour plusieurs éléments du tableau en 3.6.
Quelque chose comme
db.coll.update( {_id:235399}, {$unset: {"casts.crew.$[].withBase":""}} )
$ [] supprime toutes les propriétés withBase
du tableau crews
. Il agit comme un espace réservé pour la mise à jour de tous les éléments du tableau.
Utilisez multi true pour affecter plusieurs documents.
J'ai trouvé un moyen de désinstaller ces listes sans avoir à récupérer l'objet (ce qui signifie, juste faire une mise à jour), c'est assez hackish mais si vous avez une énorme base de données, cela fera l'affaire:
db.coll.update({},{$unset: {"casts.crew.0.withBase" : 1, "casts.crew.1.withBase" : 1} }, {multi: 1})
En d'autres termes, vous devez calculer le nombre d'objets qu'il peut y avoir dans n'importe quelle liste de documents et ajouter explicitement ces nombres, dans ce cas comme {casts.crew.NUMBER.withBase: 1}
.
De plus, pour compter le tableau le plus long dans un objet mongodb, un agrégat peut être fait, quelque chose comme ceci:
db.coll.aggregate( [ { $unwind : "$casts.crew" }, { $group : { _id : "$_id", len : { $sum : 1 } } }, { $sort : { len : -1 } }, { $limit : 1 } ], {allowDiskUse: true} )
Je veux juste souligner que ce n'est pas une jolie solution mais bien plus rapide que la récupération et la sauvegarde.