目前,我想要做的是,一旦用户登录,他就可以访问任何用户的网址并关注他们。我遇到了这个问题
TypeError: Object { _id: 54bd6b90b7d4cc8c10b40cbd,
name: 'Johnny',
username: 'batman',
__v: 0,
following: [],
followers: [] } has no method 'save'
schema.js
var UserSchema = new Schema({
name: String,
username: { type: String, required: true, index: { unique: true }},
password: { type: String, required: true, select: false },
level: String,
followers: [{ type: Schema.Types.ObjectId, ref: 'User'}],
following: [{ type: Schema.Types.ObjectId, ref: 'User'}]
});
module.exports = mongoose.model('User', UserSchema);
api.js
// this is where I'm Stuck ( Should I use put or post? for best practices)
.post(function(req, res) {
// find a current user that has logged in
User.find({ _id: req.decoded.id }, function(err, user) {
// simply follow the user by matching the id
user.following = req.params.user_id;
// save to the database ( The problem )
user.save(function(err) {
if(err) res.send(err);
res.json({ message: "Successfully followed!"})
})
});
})
问题在于.post,因为我无法保存。我应该怎么做才能将它保存到数据库中?
答案 0 :(得分:1)
您的代码中的问题是.find()
不会返回单个mongoose文档,而是返回一个文档数组,即使该数组只包含一个项目。您可以通过调用.findOne()
甚至.findById
来更正此问题,这样可以缩短格式。
如前所述,这仍然存在问题,因为在发出.save() after making modifications. For this reason MongoDB provides an
。update()`方法之前无法保证服务器上的文档尚未更改,该方法只会对通过指定的运营商提供文件。
要添加新关注者,您需要将$push
元素放到数组中:
.post(function(req, res) {
User.update(
{
"_id": req.decoded.id,
"following": { "$ne": req.params.user_id }
},
{ "$push": { "following": req.params.user_id }},
function(err, user) {
if (err) return res.send(err);
res.json({ message: "Successfully followed!"})
}
);
})
我实际检查该元素是否不存在,然后只更新那种情况。有一个$addToSet
运算符执行此操作,但我还建议您修改架构以包含" followingCount":和类似字段。这些对于查询很有用,返回"长度"并不是一件简单的事情。没有阅读整个文档的数组:
var UserSchema = new Schema({
name: String,
username: { type: String, required: true, index: { unique: true }},
password: { type: String, required: true, select: false },
level: String,
followers: [{ type: Schema.Types.ObjectId, ref: 'User'}],
following: [{ type: Schema.Types.ObjectId, ref: 'User'}],
folloersCount: Number,
followingCount: Number
});
// And in later code
User.update(
{
"_id": req.decoded.id,
"following": { "$ne": req.params.user_id }
},
{
"$push": { "following": req.params.user_id }},
"$inc": { "followingCount": 1 }
},
function(err, user) {
if (err) return res.send(err);
res.json({ message: "Successfully followed!"})
}
);
})
使用$inc
运算符增加计数器值。要执行相反操作并删除关注者,请使用$pull
User.update(
{
"_id": req.decoded.id,
"following": req.params.user_id
},
{
"$pull": { "following": req.params.user_id }},
"$inc": { "followingCount": -1 }
},
function(err, user) {
if (err) return res.send(err);
res.json({ message: "Successfully Un-followed :("})
}
);
})
当查询条件不满足时,$addToSet
无法做到并且不会触及文档。
如果您想在回复中修改文档,请改用.findOneAndUpdate()
。
因为你使用的是猫鼬,不要忘记你还在使用MongoDB。最好使用数据库运算符来修改文档,而不是在代码中进行修改。
阅读文档中的query和update运算符。事实上,请阅读all of them,因为值得学习。
答案 1 :(得分:0)
您应该使用update方法,因为这将执行原子操作,并且不会出现任何并发问题。这是因为它将执行查找查询并同时保存。
.post(function(req, res) {
User.update({ _id: req.decoded.id }, { $push: {following: req.params.user_id }}, function(err, user) {
if (err) return res.send(err);
res.json({ message: "Successfully followed!"})
});
})