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

Atualizando a referência junto com outros valores Mongoose


Os dados aqui estão contidos em coleções diferentes, portanto, nenhuma instrução de atualização única é capaz de incrementar contadores em ambos ao mesmo tempo.

Para obter uma visão consistente, você precisará "encadear" suas instruções de atualização e usar os resultados de retorno de cada uma para construir a resposta.

Dependendo de suas necessidades, você pode usar uma Promise com isso:
testSchema.statics.incrementTest = function(id) {
  var self = this;
  return new Promise(function(resolve,reject) {
    self.findByIdAndUpdate(
      id,
      {
        "$inc": {
          "points": 5,
          "numVotes": 1
        }
      },
      { "new": true }
    ).then(function(test) {
      var userModel = test.schema.path("userCreated").options.ref;
      mongoose.model(userModel).findByIdAndUpdate(
        test.userCreated,
        { "$inc": { "points": 5 } },
        { "new": true }
      ).then(function(user) {
        test.userCreated = user;
        resolve(test);
      })
    }).catch(reject)
  })
};

Que você pode invocar em seu modelo:
Test.incrementTest("56fe279d363ce91765d9e39e").then(function(test) {
    console.log(JSON.stringify(test,undefined,2));
}).catch(function(err) {
    throw err;
})

Ou você pode usar async.waterfall do async biblioteca se isso lhe convier melhor:
testSchema.statics.incrementTest = function(id,callback) {
  var self = this;

  async.waterfall(
    [
      function(callback) {
        self.findByIdAndUpdate(
          id,
          { 
            "$inc": {
              "points": 5,
              "numVotes": 1
            }
          },
          { "new": true },
          callback
        )
      },
      function(err,test) {
        if (err) callback(err);
        var userModel = test.schema.path("userCreated").options.ref;
        mongoose.model(userModel).findByIdAndUpdate(
          test.userCreated,
          { "$inc": { "points": 5 } },
          { "new": true },
          function(err,user) {
            if ( typeof(user) !== "undefined" )
                test.userCreated = user;
            callback(err,test);
          }
        );
      }
    ],
    callback
  );
};

Que tem um uso semelhante:
Test.incrementTest("56fe279d363ce91765d9e39e",function(err,test) {
    if (err) throw err;
    console.log(JSON.stringify(test,undefined,2));
})

Ambos devem retornar um resultado que mostra os dados incrementados em ambos os objetos para ambas as coleções:
{ points: 5,
  numVotes: 1,
  __v: 0,
  userCreated: { points: 5, __v: 0, _id: 56ff1aa6dba6d13e798fc894 },
  createdAt: Sat Apr 02 2016 12:04:38 GMT+1100 (AEDT),
  updatedAt: Sat Apr 02 2016 12:04:38 GMT+1100 (AEDT),
  _id: 56fe279d363ce91765d9e39e }