模型之间的猫鼬关系

时间:2013-09-02 21:25:46

标签: javascript node.js mongodb mongoose

我使用的是猫鼬,我有两个模型:Item和Hashtag Hashtag模型应仅包含名称,而Item模型应包含主题标签列表(由​​ids表示) 这就是我所做的:

var ItemSchema = new Schema({
    hashtags: [ { type: Schema.ObjectId, 'default': null, ref: 'Hashtag' } ],
}); 

var HashtagSchema = new Schema({
    name: { type: String, 'default': '', trim: true },
    items: [{ type: Schema.ObjectId, ref: 'Page' }]
});

这是我尝试创建项目的方式:

   var item = new Item({
        hashtags: ['a', 'b', 'c']
    });
    item.save(function (err, item) {
        if (err) return res.json({ error: err });
        res.json(item);
    });

不幸的是我收到了这个错误:

CastError: Cast to ObjectId failed for value "a,b,c" at path "hashtags"

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

由于您使用的是references而不是subdocuments,因此您需要先创建主题标签对象:

var tagnames = ['a','b','c'];
var hashtags = {}; //for referencing quickly by name later
for (var h in tagnames){
    var tag = new Hashtag({
        name: tagnames[h]
    });
    tag.save(function (err, item) {
        if (err) console.log('error:',err);
        hashtags[item.name] = item; 
    });
}

创建了主题标签后,您可以引用它们::

var item = new Item({
    hashtags: [hashtags.a._id,hashtags.b._id,hashtags.c._id]
});
item.save(function (err, item) {
    if (err) return res.json({ error: err });
    res.json(item);
});

然后您可以使用populate自动将对象ID转换为文档:

Item.find({})
    .populate('hashtags')
    .exec(function (err, items) {
        if (err) return handleError(err);
        //items are populated with hashtags
    });

如果您只是进行简单的标记,那么subdocuments可能更合适。它们允许您一步声明并保存子文档。权衡是子文档专属于其父文档。它们不是引用,因此必须手动完成它们的任何聚合。

相关问题