我有两个猫鼬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
数据库。然后我将允许用户更新这个Profile
db(但不是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
中的相应条目不同。
有人能指出我正确的方向吗?
您的代码的几个部分是有问题的。
你调用了newUser._id
但是newUser是mongoose模型用户的实例。 _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
,而它不是这个db的_id
,所以在这个集合中没有查询_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
在集合中查找文档Profile.findOne({user user._id}).populate({path: 'user', select: "-password"})
。此请求将删除密码字段以减少数据泄漏风险。