请教一个Nodejs Mongoose问题
请教一个Nodejs Mongoose问题
UserSchema = new Schema({
name: String,
password: String
})
var User = mongoose.model(‘User’, UserSchema)
PostSchema = new Schema({
title: String,
body: String,
user: {type : Schema.ObjectId, ref : ‘User’}
});
var Post = mongoose.model(‘Post’, PostSchema);
app.get(’/posts’, function(req, res, next){
var user = new User({name: ‘lentg’, password: ‘123’});
var post = new Post({title: ‘hello’, body: ‘world’, user: user});
console.log(post.user); 这里输出为的用户是user._id, 在别的例子中输出的都是 user对象,想问一下这是怎么回事啊?
});
当然可以!你提到的问题是关于在创建一个新的 Post
文档时,post.user
的输出结果。让我们详细解释一下这个问题,并提供一些示例代码。
问题分析
在你的代码中,post.user
是一个引用到 User
模型的 ObjectId。当你创建一个新的 Post
文档时,你传递了一个 User
对象给 user
字段。然而,Mongoose 会自动将这个 User
对象的 _id
转换为 ObjectId
类型,并存储在 Post
文档中。
示例代码
首先,我们来看一下完整的代码:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// 定义 User 模型
const UserSchema = new Schema({
name: String,
password: String
});
const User = mongoose.model('User', UserSchema);
// 定义 Post 模型
const PostSchema = new Schema({
title: String,
body: String,
user: { type: Schema.Types.ObjectId, ref: 'User' }
});
const Post = mongoose.model('Post', PostSchema);
// 创建一个新的 User 对象
const user = new User({ name: 'length', password: '123' });
// 创建一个新的 Post 对象并传递 user 对象
const post = new Post({ title: 'hello', body: 'world', user: user._id }); // 注意这里传递的是 user._id
// 保存 user 和 post 到数据库
Promise.all([user.save(), post.save()])
.then(() => {
console.log('User and Post saved successfully.');
return Post.findOne({ title: 'hello' }).populate('user');
})
.then(post => {
if (post) {
console.log(post.user); // 输出的是完整的 User 对象
}
})
.catch(err => {
console.error(err);
});
解释
-
定义模型:
UserSchema
和PostSchema
分别定义了User
和Post
的结构。PostSchema
中的user
字段是一个引用到User
模型的ObjectId
。
-
创建对象:
- 创建一个新的
User
对象并保存到数据库。 - 创建一个新的
Post
对象时,传递的是user._id
而不是整个user
对象。这样做的原因是Post
模型中的user
字段期望的是一个ObjectId
类型。
- 创建一个新的
-
保存到数据库:
- 使用
Promise.all
同时保存user
和post
。 - 通过
.populate('user')
方法查询Post
并获取完整的User
对象。
- 使用
-
输出结果:
- 在控制台中,
post.user
将输出完整的User
对象,而不是仅包含_id
的部分。
- 在控制台中,
希望这个示例代码和解释能帮助你理解为什么 post.user
的输出结果是 user._id
,以及如何通过 .populate()
方法获取完整的 User
对象。
如果不populate的话就是只输出子文档的_id
谢谢,了解了。
在你的代码中,post.user
输出的是 user._id
而不是 user
对象本身,这是因为你在创建 post
时,传递了一个未保存的 user
实例给 user
字段。Mongoose 默认不会将整个 user
对象嵌入到 post
中,而是将其 _id
嵌入进去,并且会引用对应的 User
模型。
如果你希望在 post.user
中得到完整的 user
对象,你需要先保存 user
到数据库,然后再在创建 post
时引用这个已保存的 user._id
。以下是一个修改后的示例:
const UserSchema = new Schema({
name: String,
password: String
});
const User = mongoose.model('User', UserSchema);
const PostSchema = new Schema({
title: String,
body: String,
user: { type: Schema.Types.ObjectId, ref: 'User' }
});
const Post = mongoose.model('Post', PostSchema);
app.get('/posts', async (req, res, next) => {
try {
let user = new User({ name: 'lentg', password: '123' });
await user.save(); // 保存 user
let post = new Post({ title: 'hello', body: 'world', user: user._id }); // 使用 user._id
await post.save(); // 保存 post
const loadedPost = await Post.findById(post._id).populate('user'); // 加载 post 并填充 user
console.log(loadedPost.user); // 现在 user 是一个完整的对象
res.json(loadedPost);
} catch (error) {
next(error);
}
});
在这个示例中:
- 首先保存
user
。 - 创建
post
时使用user._id
。 - 最后使用
.populate('user')
方法来加载完整的user
对象。