通过Mongoose存储MongoDB中嵌入另一个文档的文档副本

时间:2015-04-14 12:10:22

标签: node.js mongodb mongoose

我们要求将Mongo文档的副本存储为另一个文档中的嵌入式子文档。它应该引用原始文档。复制的文档需要是深层副本,就像原始快照一样。

原始文档的模式(使用Mongoose定义)不固定 - 它目前使用一种继承类型,允许根据“类型”对Schema进行不同的添加。


  1. 在Mongoose模型中有没有办法实现这种灵活的嵌入式架构?
  2. 当我们知道时,它是否需要在运行时注入 架构?

  3. 我们目前的模型/模式如下:

    ///UserList Schema: - this should contain a deep copy of a List
    user: {
        type: ObjectId,
        ref: 'User'
    },
    list: {
        /* Not sure if this is a how we should store the reference 
        type: ObjectId,  
        ref: 'List'
         */
        listId: ObjectId,
        name: {
            type: String,
            required: true
        },
        items: [{
            type: ObjectId,
            ref: 'Item'
        }]
    }
    

    ///List Schema:
    
    name: {
        type: String,
        required: true
    },
    items: [{
        type: ObjectId,
        ref: 'Item'
    }],
    createdBy: {
        type: ObjectId,
        ref: 'User'
    }   
    

    我们目前使用的代码使用继承来允许不同的项类型。我意识到这种技术可能不是实现我们所需灵活性的最佳方式,而不是我的问题的焦点。

    ///Item Model + Schema
    var mongoose = require('mongoose'),
    nodeutils = require('util'),
    Schema = mongoose.Schema,
    ObjectId = Schema.Types.ObjectId;
    
    function ItemSchema() {
        var self = this;
        Schema.apply(this, arguments);
    
        self.add({
            question: {
                type: String,
                required: true
            }
        });
    
        self.methods.toDiscriminator = function(type) {
            var Item = mongoose.model('Item');
            this.__proto__ = new Item.discriminators[type](this);
            return this;
        };
    }
    
    nodeutils.inherits(ItemSchema, Schema);
    module.exports = ItemSchema;
    

1 个答案:

答案 0 :(得分:1)

我认为您只需要在父级mongoose架构中为文档创建一个空{}对象。这样,您就可以使用所有数据的硬拷贝存储任何对象。

parentobj : {
    name: Sring,
    nestedObj: {}
}

我认为在这一点上,你需要的是在保存之前将嵌套对象标记为已修改。这是我的猫鼬代码的一个例子。

exports.update = function(req, res) {
  User.findById(req.params.id, function (err, eluser) {
    if (err) { return handleError(res, err); }
    if(!eluser) { return res.send(404); }
    var updated = _.merge(eluser, req.body);
    //This makes NESTEDDATA  OBJECT to be saved
    updated.markModified('nestedData');
    updated.save(function (err) {
      if (err) { return handleError(res, err); }
      return res.json(200, eluser);
    });
  });
};

此外,如果你需要在nestedDocument中使用不同文档的数组,那么正确的方法就是这个:

parentobj : {
    name: Sring,
    nestedObjs: [Schema.Types.Mixed]
}

请仔细检查Mongoose Schema Types

编辑

正如你所说,我会在nestedObj数组定义中添加ItemSchema作为最终解决方案,以便将对象的类型说明为确定的类型。

var ItemSchema = new Schema({
    item1: String,
    item2: String
});

var parentobj = new Schema({
    name: Sring,
    nestedObj: [ItemSchema]
});

编辑2: 记得在nestedArray中添加新项目,必须使用nestedArray.push(item)

问候!!