在api调用中更新2个mongoose模式

目前我正试图更新两个不同的用户架构在api调用。

第一个模式logging在用户模式中,我们给它一个名称= Tom第二个模式是其他用户为应用程序注册,我们给它一个名字= John

架构代码

schema.js

var mongoose = require('mongoose'); var Schema = mongoose.Schema; var bcrypt = require('bcrypt-nodejs'); var UserSchema = new Schema({ name: String, username: { type: String, required: true, index: { unique: true }}, password: { type: String, required: true, select: false }, followers: [{ type: Schema.Types.ObjectId, ref: 'User'}], following: [{ type: Schema.Types.ObjectId, ref: 'User'}], followersCount: Number, followingCount: Number }); module.exports = mongoose.model('User', UserSchema); 

api的名字是'/ follow /:user_id',我想达到的是。 每当用户Tom跟随John的其他用户时,Tom的下一个字段将被更新,John的跟随者字段也会被更新。

我目前的尝试(req.decoded.id是login用户)

api.js

 // The first way apiRouter.post('/follow/:user_id', function(req, res) { User.findOneAndUpdate( { _id: req.decoded.id, following: { $ne: req.params.user_id } }, { $push: { following: req.params.user_id}, $inc: { followingCount: 1} }, function(err, currentUser) { if (err) { res.send(err); return; } console.log(currentUser); }); User.findOneAndUpdate( { _id: req.params.user_id, followers: { $ne: req.decoded.id } }, { $push: { followers: req.decoded.id }, $inc: { followersCount: 1} }, function(err, user) { if(err) { res.send(err); return; } res.json({ message: "Successfully followed" }); } ) }); //Second way apiRouter.post('/follow/:user_id', function(req, res) { // find a current user that has logged in User.update( { _id: req.decoded.id, following: { $ne: req.params.user_id } }, { $push: { following: req.params.user_id}, $inc: { followingCount: 1} }, function(err) { if (err) { res.send(err); return; } User.update( { _id: req.params.user_id, followers: { $ne: req.decoded.id } }, { $push: { followers: req.decoded.id }, $inc: { followersCount: 1} } ), function(err) { if(err) return res.send(err); res.json({ message: "Successfully Followed!" }); } }); }); 

两者都有问题,

第一种方法:问题是'不能设置已经发送的头',因为在一个api调用中有两个单独的mongoose查询,所以它响应两次,这就是为什么我得到这个错误。

第二种方法:问题是,login用户(Tom)的以下字段被更新,而另一个用户的追随者字段(John)则返回null。 我控制台login这两个值,以及与POSTMAN铬应用程序testing。

借我你的想法家伙!

第二种方式是正确的(可以改善两个并行运行)我猜这个问题是在另一个地方。 我不知道你正在使用哪个框架,但我猜字段_id是从mongoDB,是一个ObjectId ,看起来像decoded.id可以是一个objectId,而来自请求的那个当然只是一个string。 所以我猜这是空的,因为它没有find任何用户与该string。

尝试使其成为一个objectId超出该string(reffering req.params.user_id在第二个查询中)

你采取的第一条路线似乎很好。

然而,正如@cdbajorin提到的,错误“不能发送已经发送的头”与mongoose没有任何关系,但事实上,你正在尝试设置头后发送响应到客户端已经。 ( 看到这个可爱的答案 )

我的build议是在发送响应之前确保两个数据库调用都成功。

在这种情况下,您可能还需要考虑两阶段提交 ,因为MongoDB不支持传统的数据库事务,并且每次更新两个文档。 如果由于某种原因数据库调用失败,应该采取恢复到稳定状态的过程。

第一种方法可以通过两种方式来改进。 一个是在更新下面字段的callback里面更新followers字段。 另一种方式是使用asynchronous瀑布。 我build议去async瀑布(npmasynchronous瀑布)。