MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Como atualizar vários objetos de matriz no mongodb


Embora eu não ache que iterar sobre uma contagem esperada seja a "melhor" maneira de fazer isso, aqui estão basicamente as correções para o que você está tentando fazer, com alguma ajuda do nó async biblioteca para controle de fluxo:
  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
    }
  );

Portanto, o principal aqui é que seu .update() Em vez disso, a instrução deve estar procurando pelo "events.handled.visibile": false correspondências, e é claro que você precisa ter certeza de que as operações são executadas "em série", caso contrário, não há garantia real de que você está de fato pegando o documento em um estado alterado do .update() anterior .

O async.whilst manipula o controle de fluxo para que ele aguarde a conclusão de cada .update() até executar o próximo. Quando a primeira declaração lógica é true ( contador esgotado ) e todos os .update() instruções são executadas, o loop será liberado para o retorno de chamada final.

Sempre que possível, você deve usar as operações de atualização "em massa", conforme mencionado na resposta que você está seguindo a> . Isso envia todas as atualizações e tem apenas uma resposta, de modo que a sobrecarga de aguardar a conclusão de cada operação é eliminada.