sql >> Base de Datos >  >> NoSQL >> MongoDB

Cómo actualizar objetos de matriz múltiple en mongodb

Si bien no creo que iterar sobre un conteo esperado sea la "mejor" manera de hacer esto, aquí están básicamente las correcciones de lo que está tratando de hacer, con algo de ayuda del nodo async biblioteca para control de flujo:

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

Entonces, lo principal aquí es que su .update() en su lugar, la declaración debería buscar "events.handled.visibile": false coincidencias y, por supuesto, debe asegurarse de que las operaciones se ejecuten "en serie", de lo contrario, no hay una garantía real de que, de hecho, esté tomando el documento en un estado alterado del anterior .update() .

El async.whilst maneja el control de flujo para que espere la finalización de cada .update() hasta ejecutar el siguiente. Cuando su primera declaración lógica es true (contador agotado) y todo .update() se ejecutan las declaraciones, luego el ciclo se liberará a la devolución de llamada final.

Siempre que sea posible, debería usar operaciones de actualización "en masa" como se indica en la respuesta que está siguiendo . Eso envía todas las actualizaciones y una vez y solo tiene una respuesta, por lo que se elimina la sobrecarga de esperar a que se complete cada operación.