MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Come aggiornare più oggetti Array in mongodb

Anche se non penso che l'iterazione su un conteggio previsto sia il modo "migliore" per farlo, ecco fondamentalmente le correzioni a ciò che stai cercando di fare, con un po' di aiuto dal nodo async libreria per il controllo del flusso:

  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
    }
  );

Quindi le cose principali qui sono che il tuo .update() l'istruzione dovrebbe invece cercare il "events.handled.visibile": false corrispondenze, e ovviamente devi assicurarti che le operazioni vengano eseguite "in serie", altrimenti non c'è alcuna garanzia reale che tu stia effettivamente acquisendo il documento in uno stato alterato rispetto al precedente .update() .

Il async.whilst gestisce il controllo di flusso in modo che attenda il completamento di ogni .update() fino all'esecuzione del successivo. Quando la sua prima istruzione logica è true ( contatore esaurito ) e tutti i .update() vengono eseguite le istruzioni, quindi il ciclo verrà rilasciato alla richiamata finale.

Ove possibile, dovresti davvero utilizzare le operazioni di aggiornamento "bulk" come indicato nella risposta che stai seguendo . Questo invia tutti gli aggiornamenti e ha una sola risposta, quindi il sovraccarico di attesa per il completamento di ogni operazione viene eliminato.