我使用的是猫鼬,我有两个模型: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"
我该如何解决这个问题?
答案 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可能更合适。它们允许您一步声明并保存子文档。权衡是子文档专属于其父文档。它们不是引用,因此必须手动完成它们的任何聚合。