请教一个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对象。

