您列出的代码没有问题,因此是您没有向我们展示导致问题的代码。
当您引用时,您将在集合中保存对象的副本,并将相关的 ObjectId 值添加到您的案例中“回复”中的对象数组中。
有几种方法可以做到这一点,但一种安全的 MongoDB 方法是使用 $push 添加其他项目。
作为一个完整的例子:
var async = require('async'),
mongoose = require('mongoose'),
Schema = mongoose.Schema;
var userSchema = new Schema({
"name": String
});
var messageSchema = new Schema({
"sender": { "type": Schema.Types.ObjectId, "ref": "User" },
"replies": [{ "type": Schema.Types.ObjectId, "ref": "Message" }],
"roomId": String,
"sendTime": { "type": Date, "default": Date.now },
"content": String,
"parentId": Schema.Types.ObjectId
});
var Message = mongoose.model( "Message", messageSchema );
var User = mongoose.model( "User", userSchema );
mongoose.connect('mongodb://localhost/test');
async.waterfall(
[
// Clean up samples
function(callback) {
async.each(
[User,Message],
function(model,callback) {
model.remove({},callback);
},
callback
)
},
// Create user
function(callback) {
User.create({ "name": "Bill" },callback);
},
// Create a message
function(user,callback) {
Message.create({
"sender": user._id,
"roomId": "1",
"content": "message"
},function(err,message) {
callback(err,user,message);
});
},
// Create a reply
function(user,message,callback) {
Message.create({
"sender": user._id,
"roomId": "1",
"content": "reply",
"parentId": message._id
},callback);
},
// Save that reply on the parent
function(message,callback) {
Message.findByIdAndUpdate(
message.parentId,
{ "$push": { "replies": message._id } },
function(err,message) {
console.info( message );
callback(err);
}
);
},
// List that
function(callback) {
Message.find({},function(err,messages) {
if (err) callback(err);
console.log(
"All:\n%s",
JSON.stringify( messages, undefined, 4 )
);
callback();
});
}
],
function(err) {
if (err) throw err;
mongoose.disconnect();
}
);
还有输出:
{ _id: 54f3dff198a8c85306a2ef67,
sender: 54f3dff198a8c85306a2ef66,
roomId: '1',
content: 'message',
__v: 0,
sendTime: Mon Mar 02 2015 14:58:41 GMT+1100 (AEDT),
replies: [ 54f3dff198a8c85306a2ef68 ] }
All:
[
{
"_id": "54f3dff198a8c85306a2ef67",
"sender": "54f3dff198a8c85306a2ef66",
"roomId": "1",
"content": "message",
"__v": 0,
"sendTime": "2015-03-02T03:58:41.387Z",
"replies": [
"54f3dff198a8c85306a2ef68"
]
},
{
"_id": "54f3dff198a8c85306a2ef68",
"sender": "54f3dff198a8c85306a2ef66",
"roomId": "1",
"content": "reply",
"parentId": "54f3dff198a8c85306a2ef67",
"__v": 0,
"sendTime": "2015-03-02T03:58:41.393Z",
"replies": []
}
]
这样,如果您在存在“回复”的消息上调用 .populate(),它将返回集合并检索相关数据,并使数据看起来也是该项目的一部分。
请注意,如果没有您自己的干预,这种魔法不会“递归”发生。它只是一个基本的帮手,所以如果你想要更多,那么你仍然需要自己做。