0

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

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"

我该如何解决这个问题?

4

1 回答 1

2

由于您使用的是引用而不是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
    });

如果您只是做简单的标记,那么子文档可能更适合。它们允许您在一个步骤中声明和保存子文档。权衡是子文档只属于它们的父文档。它们不是引用,因此必须手动完成对它们的任何聚合。

于 2013-09-02T22:35:00.817 回答