架构错误,'has no method save'
Schema Error, 'has no method save'
目前我想做的是,一旦用户登录,他就可以转到任何用户的 url 并关注他们。我遇到了这个问题
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 中,因为我无法保存。我应该怎么做才能将其保存到数据库中?
您应该使用更新方法,因为这将执行原子操作并且不容易出现任何并发问题。这是因为它会同时执行查找查询和保存。
.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!"})
});
})
您的代码中的问题是 .find()
does not return a single mongoose document but rather an array of documents even if that array contains only a single item. You can correct this by calling .findOne()
or even .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": 和类似字段。这些对于查询很有用,在不阅读整个文档的情况下 return 数组的 "length" 并不是一件简单的事情:
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
operator. To do the reverse and remove a follower use $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()
。
所以不要因为你在使用 mongoose,就忘记了你基本上还在使用 MongoDB。最好使用数据库操作符来修改文档,而不是在代码中进行这些修改。
阅读 query and update operators in the documentation. In fact read up on all of them,因为它值得学习。
目前我想做的是,一旦用户登录,他就可以转到任何用户的 url 并关注他们。我遇到了这个问题
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 中,因为我无法保存。我应该怎么做才能将其保存到数据库中?
您应该使用更新方法,因为这将执行原子操作并且不容易出现任何并发问题。这是因为它会同时执行查找查询和保存。
.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!"})
});
})
您的代码中的问题是 .find()
does not return a single mongoose document but rather an array of documents even if that array contains only a single item. You can correct this by calling .findOne()
or even .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": 和类似字段。这些对于查询很有用,在不阅读整个文档的情况下 return 数组的 "length" 并不是一件简单的事情:
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
operator. To do the reverse and remove a follower use $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()
。
所以不要因为你在使用 mongoose,就忘记了你基本上还在使用 MongoDB。最好使用数据库操作符来修改文档,而不是在代码中进行这些修改。
阅读 query and update operators in the documentation. In fact read up on all of them,因为它值得学习。