Mongoose 3.8 中的 ObjectId 数组
Array of ObjectIds in Mongoose 3.8
我有一个名为 Message 的模式,它有一个 属性 replies
也是 Message 对象。我试图在猫鼬中定义它,但 replies
一直返回未定义。
var MessageSchema = new Schema({
sender: {
type: Schema.ObjectId,
ref: 'User'
},
replies: [{type:Schema.ObjectId, ref:'Message'}],
roomId: String,
sendTime: Date,
content: String,
parentId: Schema.ObjectId
});
我也试过 replies: [MessageSchema]
和 replies:[Schema.ObjectId]
但它们都返回未定义。
您列出的代码没有任何问题,所以是您没有向我们展示导致问题的原因。
当您引用时,您将在集合中保存该对象的副本,并将该相关的 ObjectId 值添加到您的情况下 "reply" 中的对象数组中。
有几种方法可以做到这一点,但一种比较安全的 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": []
}
]
这样,如果您在 "replies" 存在的消息上调用 .populate()
,它将返回到集合并检索相关数据,并使数据看起来像是该项目的一部分还有。
请注意,如果没有您自己的干预,这样的魔法就不会发生 "recursively"。这只是一个基本的帮手,所以如果你想要更多,你还是得自己做。
我有一个名为 Message 的模式,它有一个 属性 replies
也是 Message 对象。我试图在猫鼬中定义它,但 replies
一直返回未定义。
var MessageSchema = new Schema({
sender: {
type: Schema.ObjectId,
ref: 'User'
},
replies: [{type:Schema.ObjectId, ref:'Message'}],
roomId: String,
sendTime: Date,
content: String,
parentId: Schema.ObjectId
});
我也试过 replies: [MessageSchema]
和 replies:[Schema.ObjectId]
但它们都返回未定义。
您列出的代码没有任何问题,所以是您没有向我们展示导致问题的原因。
当您引用时,您将在集合中保存该对象的副本,并将该相关的 ObjectId 值添加到您的情况下 "reply" 中的对象数组中。
有几种方法可以做到这一点,但一种比较安全的 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": []
}
]
这样,如果您在 "replies" 存在的消息上调用 .populate()
,它将返回到集合并检索相关数据,并使数据看起来像是该项目的一部分还有。
请注意,如果没有您自己的干预,这样的魔法就不会发生 "recursively"。这只是一个基本的帮手,所以如果你想要更多,你还是得自己做。