MongoDB mettre à jour les données dans le champ imbriqué

J'utilise Mongo pour être ma base de données. j'ai une donnée:

 {
   _id : '123'
   friends: [
     {name: 'allen', emails: [{email: '11111', using: 'true'}]}
   ]
 }

Maintenant, je veux motify les emails des amis de l'utilisateur, dont _id est '123' j'écris comme ceci:

db.users.update ({_id: '123'}, {$set: {"friends.0.emails.$.email" : '2222'} })

C'est facile, mais c'est FAUX , Quand le tableau d'emails a deux données ou plus. donc, ma question est: Comment puis-je motify les données dans un fichier imbriqué - - - juste avoir deux ou plusieurs tableaux imbriqués? Grâce.

35
demandé sur GolfWolf 2013-10-26 10:10:45

3 réponses

Vous devez utiliser la Notation par points pour les tableaux.

Autrement dit, vous devez remplacer le $ par l'index basé sur zéro de l'élément que vous essayez de mettre à jour.

Par exemple:

db.users.update ({_id: '123'}, { '$set': {"friends.0.emails.0.email" : '2222'} });

Mettra à jour le premier e-mail du premier ami, et

db.users.update ({_id: '123'}, { '$set': {"friends.0.emails.1.email" : '2222'} })

Mettra à jour le deuxième e-mail du premier ami.

58
répondu GolfWolf 2015-11-19 09:19:08

Mettre à jour quelque chose dans un arry multi-niveau est vraiment une douleur dans le cul, ma façon de le faire:remplacer le niveau profond arry.

db.user.findOne({_id:'123'},{friends:1}).lean().exec(function(err,user){
   var whichArrayToUpdate;
   for (var ii = 0; ii < user.friends.length; ii++) {
        for (var jj = 0; i < user.friends[ii].emails; jj++) {
            if(user.friends[ii].emails[jj].email == '1111' ){// update it below

                user.friends[ii].emails[jj].email == 'what ever you want to set to.';

                whichArrayToReplace = user.friends[ii].emails;
                break;
            }
        };
   };

   db.user.update({'friends.name':'allen'},{$set{'friends.$.email': whichArrayToReplace} })
})

, Mais, pourquoi ne pas utiliser la méthode save ()? le save() remplacera tout votre document, si votre document est petit, c'est ok , mais si votre document est relly grand, c'est une meilleure idée de remplacer juste une partie de votre document.

Ou faites la boucle, utilisez la position du tableau de niveau supérieur et du tableau de deuxième niveau(ii et jj) pour mettre à jour.

Mon conseil est: quand vous schéma de conception, ne mettez pas de tableau dans un autre tableau sauf si vous ne ferez aucune mise à jour pour ce tableau.

1
répondu Eisneim 2014-04-19 06:43:59

Solution utilisant Mangouste:

    Users.findById("123", function(err, user) {

      var friends = user.friends;
        for ( i=0; i < friends.length; i++ ) {
          if (friends[i].name == 'allen') {
            friends[i].email = '2222';

            user.save(function(err) {
              if (err) throw err;
              console.log("email updated");
            });
          } else {
            console.log("no friends named allen");
          }
        }

    }
1
répondu Kacper 2018-09-29 22:14:29