我有两个Mongoose DB模式,一个User
和一个Profile
:
var userSchema = new mongoose.Schema({
username: String,
password: String,
type: String
});
userSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", userSchema);
var profileSchema = new mongoose.Schema({
username: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
email: {
type: String,
default: ""
},
skill: {
type: String,
default: ""
}
});
module.exports = mongoose.model("Profile", profileSchema);
我首先使用passport-js注册并验证用户,如果成功,那么我想用Profile
和username
创建填充type
db。然后,我将允许用户更新此Profile
数据库(但不能更新Users
)。在docs之后,我尝试使用.populate
在Profile
中创建一个条目,其条目与User
中的信息相同:
router.post("/signup", function(req, res) {
var newUser = new User({username: req.body.username, type: req.body.type});
User.register(newUser, req.body.password, function(err, user){
if(err){
console.log(err.message);
return res.render("signup");
}
passport.authenticate("local")(req, res, function(){
Profile.findById(newUser._id).populate("username").exec(function(err, foundUser){
if(err){
console.log("Problem populating the profiles DB");
}
else{
console.log("New user:" + newUser._id);
res.redirect("profile/" + newUser._id);
}
});
});
});
});
这顺利通过,但是我的Profiles
数据库为空。
有人在这里看到我在做什么错吗?
我也尝试过(在同一条路线内):
Profile.create(newUser, function(err, newlyCreated){
if(err){
console.log(err);
} else {
console.log("Added user to profile db:" + newUser._id);
console.log("New user:" + newUser._id);
res.redirect("profile/" + newUser._id);
}
});
但这失败并显示错误:
{ DocumentNotFoundError: No document found for query "{ _id: 5c6d9512a4a301b73b565681 }"
我正在尝试的另一种方法是
Profile.create({username:req.body.username, type: req.body.type}, function(err, pro){
if(err){
console.log("Profile error: " + err);
} else {
console.log("Added user to profile db:" + newUser._id);
console.log("New user:" + newUser._id);
res.redirect("profile/" + newUser._id);
}
});
通过,但在Profiles
中产生一个条目,其条目_id
与Users
中的相应条目不同。
有人能指出我正确的方向吗?
答案 0 :(得分:1)
您的代码的几个部分是有问题的。
您叫newUser._id
,但是newUser是猫鼬模型User的实例。 _id
字段是由MongoDB在将文档存储到数据库时创建的,因此逻辑上,仅实例化对象时不会填充该字段。将其保存到数据库时创建。因此,您可以访问_id
上的正确user._id
,其中user
来自回调。
router.post("/signup", function(req, res) {
var newUser = new User({username: req.body.username, type: req.body.type});
User.register(newUser, req.body.password, function(err, user){
if(err){
console.log(err.message);
return res.render("signup");
}
passport.authenticate("local")(req, res, function(){
Profile.findById(user._id).populate("username").exec(function(err, foundUser){
if(err){
console.log("Problem populating the profiles DB");
}
else{
console.log("New user:" + user._id);
res.redirect("profile/" + user._id);
}
});
});
});
});
此外,您的代码中还有一些奇怪的部分:
profiles
集合中创建新的个人资料。那么您如何看待它可以找到未创建的文档。 .findById
并将其从用户文档中传递为_id
,但它不是此数据库的_id
,因此没有包含查询的{ {1}}。 _id
,然后尝试在您的字段中填充:Profile.findOne({username: user.name})
存储配置文件时,请使用Profile.findOne({username: user.name}).populate('user')
。 profile.user = user._id
查找相关文档,因此将唯一值存储到个人资料中即可轻松找到它。因此您的架构应该看起来有点不同:
user._id
,通过此调用var profileSchema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
email: {
type: String,
default: ""
},
skill: {
type: String,
default: ""
}
});
填充后,您将得到:
Profile.findOne({user: user._id}).populate('user')
记住:
{
user: {
username,
password,
type
},
email,
skill
}
属性内引用user._id
。profile.user
将通过Collection.findById(id)
document._id === id
。该请求将删除密码字段,以减少数据泄漏的风险。