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"。这只是一个基本的帮手,所以如果你想要更多,你还是得自己做。