我无法让Mongoose在运行find()时显示子文档,而它在MongoDB外壳中显示得很好。
子文档应该基于我的模式嵌入,而不是引用对象ID,所以我不应该运行任何黑魔法巫术来显示我的数据。
const UserSchema = new mongoose.Schema({
username: String;
xp: Number;
//etc.
});
const RoomSchema = new mongoose.Schema({
timestamp: { type: Date, default: Date.now },
status: { type: String, enum: ["pending", "ongoing", "completed"]},
players: {
type: [{
points: { type: Number, default: 0 },
position: String,
user: UserSchema
}],
maxlength:2
}
});
添加新房间后,请执行以下操作:
let room = new Room(coreObj);
room.players.push({
points: 0,
position: 'blue',
user: userObj //where userObj is a result of running findById on User model
});
它在mongo外壳中显示得很好,当运行db.rooms.find({}).pretty()时,我可以看到已经添加了完整的文档。但是,在Mongoose模型上运行时:
Room.find({}).exec((err,rooms)=>{
console.log(rooms[0].toJSON());
});
我没有看到用户子文档,而且我完全看不到用户域!什么地方出问题了?
从Mongoose模型记录的json:
{
"status": "pending",
"_id": "5cf5a25c050db208641a2076",
"timestamp": "2019-06-03T22:42:36.946Z",
"players": [
{
"points": 0,
"_id": "5cf5a25c050db208641a2077",
"position": "blue"
}
],
"__v": 0
}
来自Mongo Shell的Json:
{
"_id" : ObjectId("5cf5a25c050db208641a2076"),
"status" : "pending",
"timestamp" : ISODate("2019-06-03T22:42:36.946Z"),
"players" : [
{
"points" : 0,
"_id" : ObjectId("5cf5a25c050db208641a2077"),
"position" : "blue",
"user" : {
"xp" : 0,
"_id" : ObjectId("5cf2da91a45db837b8061270"),
"username" : "bogdan_zvonko",
"__v" : 0
}
}
],
"__v" : 0
}
3条答案
按热度按时间w41d8nur1#
考虑到最佳实践,我认为在
RoomSchema
中引用UserSchema
会更合适。类似于:然后将
user._id
存储在该字段中。这样,如果用户被修改,您的
RoomSchema
将始终引用正确的信息。然后,您可以使用Mongoose的populate
获得用户oyt4ldly2#
我不能完全确定为什么您看不到子文档,但这个代码示例为我正确地打印了它。示例最初发布在https://mongoosejs.com/docs/subdocs.html中,但稍作修改以包含子文档,使其看起来类似于您的代码:
执行此代码会导致:
这是使用Mongoose 5.5.12进行测试的。
注意,我使用
JSON.stringify()
而不是Mongoose的toJSON()
打印文档。eh57zj3b3#
我刚刚遇到了一个非常相似的问题,我想我明白了。关键在于你所使用的模型:
但之后你就会
因此,您缺少“type”子字段,因此您的文档不符合您的RoomSchema,而且Mongoose不会显示不符合架构的部分。