【问题标题】:mongoose: How to insert a single subdocument - not an array猫鼬:如何插入单个子文档 - 而不是数组
【发布时间】:2014-05-13 09:50:41
【问题描述】:

在猫鼬中,您可以按照以下方式声明子文档的架构:

        var childSchema = new mongoose.Schema({ name: String, age: String });
        var parentSchema = new mongoose.Schema({
            children: [childSchema]
        });
        var Parent = mongoose.model('Parent', parentSchema);
        var Child = mongoose.model('Child', childSchema);

        var child = new Child({name:'Joe', age: '21'});
        var parent = new Parent();

        parent.children = [child];

        parent.save(function(err, saved) {
            if(err) console.error(err);
        });

似乎子文档类型需要是一个数组。我需要能够将子文档保存为单个实例,而不是数组,即:

        var childSchema = new mongoose.Schema({ name: String, age: String });
        var parentSchema = new mongoose.Schema({
            children: childSchema // not an array
        });
        var Parent = mongoose.model('Parent', parentSchema);
        var Child = mongoose.model('Child', childSchema);

        var child = new Child({name:'Joe', age: '21'});
        var parent = new Parent();

        parent.children = child; // not an array

        parent.save(function(err, saved) {
            if(err) console.error(err);
        });

所以不是数组或引用,只是一个实例子文档。这可能吗?如果不应该使用:

var childInstance = child.toObject();

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    有时很难看得很清楚。您不需要另一个模式来实现您想要的。您可以像这样在父架构中简单地定义子文档:

        var parentSchema = new mongoose.Schema({
            child: { 'name' : String, 'age' : Number }  // not an array, just a sub document
        });
        var Parent = mongoose.model('Parent', parentSchema);
    
        var parent = new Parent();
        parent.child.name = "Joe";
        parent.child.age  = 13;
    
        parent.save(function(err, saved) {
            if(err) console.error(err);
        });
    

    【讨论】:

    【解决方案2】:

    哎呀!编辑:

    我完全误解了你的问题。所以你想存储一个 single 子文档?那为什么你把属性命名为children..

    你可以使用:

    var ParentSchema    =   new schema({
        name : String,
        child: Object
    });
    
    // etc.
    
    john.child = new Child({name: 'kiki'});
    // which is actually the same as: john.child = {name:'kiki'};
    john.save();
    

    这样,mongoose 将文档转换为一个简单的对象并存储它。但我看不出这样做有什么用?它没有 Schema 的好处,而是使用默认对象。不将其放入数组也会阻止您添加更多嵌套项。

    旧:

    您需要先将它们链接起来,而不是将子架构直接注入到父架构中(并且您想单独存储它们对吗?)。

    所以我们得到两个集合:parentschildren (=Parent && Child)。集合children 的所有文档都链接到特定的parents 集合。一个parent 文档链接了零个、一个或多个children 文档。

    通过这种方式,您可以保持修改架构的能力(例如附加 methodsstatics)并保持文档整齐地分开,并且您可以获得所需的“孩子”效果:

    //  get mongoose.
    var mongoose = require('mongoose');
    
    //  connect to your local pc on database myDB.
    mongoose.connect('mongodb://localhost:27017/myDB');
    
    //  parent schema.
    var parentSchema = new mongoose.Schema({
      name     : String,
      //  the ObjectId's of the children links the two schema's.
      children   : [{type:mongoose.Schema.Types.ObjectId, ref:'Child'}]
    });
    
    //  child schema.
    var childSchema = new mongoose.Schema({
      name   : String,
      //  the parent's ObjectId links to the owner.
      parent : {type:mongoose.Schema.Types.ObjectId, ref:'Parent'}
    });
    
    //  model the schema's.
    var Child   = mongoose.model('Child', childSchema),
        Parent  = mongoose.model('Parent', parentSchema);
    
    //  create a 'parent'.
    //  we are not assigning the children yet.
    var john     = new Parent({name:'John'});
    
    //  create two children and save them. Link them to john.
    var child1   = new Child({name:'Mimi', parent:john._id}),
        child2   = new Child({name:'Kiki', parent:john._id});
    
    //  push child to children property of john.
    john.children.push(child1);
    john.children.push(child2);
    
    //  save everything.
    john.save();
    child1.save();
    child2.save();
    

    这将返回以下内容:

    /**
    Children: 
    [ { name: 'Mimi',                                                                                                                                                                                                                            
        parent: 537258f63eb92b3201b65e56,                                                                                                                                                                                                        
        _id: 537258f63eb92b3201b65e57,                                                                                                                                                                                                           
        __v: 0 },                                                                                                                                                                                                                                
      { name: 'Kiki',                                                                                                                                                                                                                            
        parent: 537258f63eb92b3201b65e56,                                                                                                                                                                                                        
        _id: 537258f63eb92b3201b65e58,                                                                                                                                                                                                           
        __v: 0 } ]
    
    Parent:
    [ { name: 'John',                                                                                                                                                                                                                            
        _id: 537258f63eb92b3201b65e56,                                                                                                                                                                                                           
        __v: 0,                                                                                                                                                                                                                                  
        children: [ 537258f63eb92b3201b65e57, 537258f63eb92b3201b65e58 ] } ]
    */
    

    你也可以做一个静态函数来收集parents:addChild(child, callback),这样代码看起来更干净(javaish风格)。

    伪代码:

    // add custom static method.
    parentSchema.statics.addChild = function(child, callback) {
       // implementation.
    }
    
    // the way you call this method:
    parentModel.addChild(new Child.etc..);
    

    希望这会有所帮助并祝你好运(:

    【讨论】:

    • 如果父母有数百个孩子并且我不想使用数组(出于性能原因),我可以看到这种方法的优势。
    【解决方案3】:

    如果 2 个集合的关系是 1 对 1。 你可以使用'ref'

    var personSchema = Schema({
      _id     : Number,
      name    : String,
      age     : Number,
      stories : [{ type: Schema.Types.ObjectId, ref: 'Story' }]
    });
    
    var storySchema = Schema({
      _creator : { type: Number, ref: 'Person' },
      title    : String,
      fans     : [{ type: Number, ref: 'Person' }]
    });
    

    来源:http://mongoosejs.com/docs/populate.html

    【讨论】:

      猜你喜欢
      • 2012-08-26
      • 2015-06-26
      • 1970-01-01
      • 1970-01-01
      • 2017-02-25
      • 2020-02-16
      • 2020-07-27
      • 2021-01-12
      • 1970-01-01
      相关资源
      最近更新 更多