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

Actualización de referencia junto con otros valores Mongoose

Los datos aquí están contenidos en diferentes colecciones, por lo que ninguna declaración de actualización única puede incrementar los contadores en ambos al mismo tiempo.

Para obtener una vista consistente, necesitará "encadenar" sus declaraciones de actualización y usar los resultados devueltos de cada una para construir la respuesta.

Dependiendo de sus necesidades, puede usar una Promise con esto:

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 luego puede invocar en su modelo:

Test.incrementTest("56fe279d363ce91765d9e39e").then(function(test) {
    console.log(JSON.stringify(test,undefined,2));
}).catch(function(err) {
    throw err;
})

O puede usar async.waterfall desde el async biblioteca si te conviene más:

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 tiene un uso similar:

Test.incrementTest("56fe279d363ce91765d9e39e",function(err,test) {
    if (err) throw err;
    console.log(JSON.stringify(test,undefined,2));
})

Ambos deberían devolverle un resultado que muestre los datos incrementados en ambos objetos para ambas colecciones:

{ 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 }