MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Comment mettre à jour plusieurs objets Array dans mongodb

Bien que je ne pense pas que l'itération sur un nombre attendu soit la "meilleure" façon de le faire, voici essentiellement les corrections à ce que vous essayez de faire, avec l'aide du nœud async bibliothèque pour le contrôle de flux :

  async.waterfall(
    [
      function(callback) {
        collection.aggregate(
          [
            { "$match": { "_id": ObjectId("4d2d8deff4e6c1d71fc29a07") } },
            { "$unwind": "$events" },
            { "$match": { "events.handled.visibile": false } },
            { "$group": {
              "_id": "$_id",
              "count": { "$sum": 1 }
            }}
          ],
          callback
        );
      },

      function(results,callback) {
        console.log(results);
        var result = results[0];

        async.whilst(
          function() { return result.count-- },
          function(callback) {
            collection.update(
              { "_id": result._id, "events.handled.visibile": false },
              { "$set": { "events.$.handled.visibile": true } },
              callback
            )
          },
          callback
        );
      }
    ],
    function(err) {
      if (err) throw err;
      // finished now
    }
  );

Donc, les choses principales ici sont que votre .update() l'instruction doit plutôt rechercher le "events.handled.visibile": false correspond, et bien sûr vous devez vous assurer que les opérations s'exécutent "en série", sinon il n'y a aucune garantie réelle que vous récupérez en fait le document dans un état modifié à partir du précédent .update() .

Le async.whilst gère le contrôle de flux afin qu'il attende la fin de chaque .update() jusqu'à l'exécution de la suivante. Quand sa première instruction logique est true ( compteur épuisé ) et tous les .update() instructions sont exécutées, la boucle sera libérée jusqu'au rappel final.

Dans la mesure du possible, vous devriez vraiment utiliser les opérations de mise à jour "en masse" comme indiqué dans la réponse que vous suivez . Cela envoie toutes les mises à jour et n'a qu'une seule réponse, de sorte que la surcharge liée à l'attente de la fin de chaque opération est éliminée.