【问题标题】:Storing a copy of a document embedded in another document in MongoDB via Mongoose通过 Mongoose 在 MongoDB 中存储嵌入在另一个文档中的文档的副本
【发布时间】:2015-06-20 00:56:52
【问题描述】:

我们需要将 Mongo 文档的副本存储为另一个文档中的嵌入子文档。它应该有对原始文件的引用。复制的文档需要是深层副本,例如原始文件的快照。

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


  1. 有没有办法在 Mongoose 模型中实现如此灵活的嵌入式架构?
  2. 是不是需要在运行时注入,什么时候才能知道 架构?

我们目前拥有的模型/模式如下所示:

///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;

【问题讨论】:

  • 问题格式很好!
  • 只是出于好奇:这个要求从何而来?在我看来,这是非常无用的数据冗余。
  • 通常是这样,但在这种情况下,我们需要复制当时存在的一些数据,因为源数据可能会更改。重要的是,用户拥有当时存在的数据副本。
  • 我为计费应用做了同样的事情,允许维护数据的完整硬拷贝。之后,当用户列出它的数据时,尽管用户进行了新的配置,但一切都是如此。

标签: node.js mongodb mongoose


【解决方案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);
    });
  });
};

另外,如果需要嵌套文档中不同文档的数组,正确的做法是这样的:

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

请仔细检查Mongoose Schema Types

编辑

正如你所说,我将添加你最终的解决方案,将 ItemSchema 包括在嵌套的Obj 数组定义中,以明确对象的类型到确定的类型。

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

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

编辑 2: 记住向 nestedArray 添加新 Item,必须使用 nestedArray.push(item)

问候!!

【讨论】:

  • 我在我的列表模式中添加了items: [ItemSchema],这似乎可以满足我的需要,因为所有这些项目都将从 ItemSchema 继承。如果您希望更新您的答案以包含此内容,我将很乐意接受您的回答。
  • 但是你说它在同一个地方是不同的 schemaType,那是混合的,不是吗???还添加 itens:[ItemSchema] 以使解决方案完整! .. 谢谢!!
猜你喜欢
  • 2016-12-14
  • 2014-11-15
  • 1970-01-01
  • 1970-01-01
  • 2011-09-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-04
  • 2014-12-28
相关资源
最近更新 更多