mongoose:如何插入单个子文档 - 而不是数组

时间:2014-05-13 09:50:41

标签: node.js mongodb mongoose

在mongoose中,您可以按照以下方式声明子文档的模式:

        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);
        });

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

var childInstance = child.toObject();

3 个答案:

答案 0 :(得分:5)

有时很难看清楚。您不需要另一个架构来实现您想要的。您可以在父模式中定义子文档,如下所示:

    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);
    });

答案 1 :(得分:4)

OOPS!编辑:

我完全误解了你的问题..所以你想存储单个子文档?那你为什么要把这个属性命名为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),因此代码看起来更干净(javaísh风格)。

<强>伪码:

// add custom static method.
parentSchema.statics.addChild = function(child, callback) {
   // implementation.
}

// the way you call this method:
parentModel.addChild(new Child.etc..);

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

答案 2 :(得分:0)

如果2个集合的关系是1比1。 你可以使用&#39; ref&#39;

    <asp:HiddenField ID="hdDate" runat="server" 
value="<%# YourClassName.GetCurrentTime()%>" />

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