在Mongoose中填充inheritance的文档

我正在尝试为以下模型创build一个数据库模式:

在这里输入图像说明

我不知道什么是更好的方式来表示这个在MongoDb将是,但因为我使用Mongoose和有一个插件的inheritance,我想下面的:

var mongoose = require('mongoose') , extend = require('mongoose-schema-extend') , Schema = mongoose.Schema , ObjectId = mongoose.Schema.Types.ObjectId var db = mongoose.connection; db.on('error', console.error.bind(console, 'connection error:')); db.once('open', function callback () { //Mashup and Item are bound (itemSchema is a sub-doc) var itemSchema = new Schema({ pos: { top: Number, left: Number } , size: { width: Number, height: Number } , component: { type: ObjectId, ref: 'Component' } }) var mashupSchema = new Schema({ name: String , desc: String , size: { width: Number, height: Number } , items: [itemSchema] }) var componentSchema = new Schema({ name: String , desc: String }, { discriminatorKey : '_type' }) var imageComponentSchema = componentSchema.extend({ url: String }) var textComponentSchema = componentSchema.extend({ text: String }) var htmlComponentSchema = componentSchema.extend({ html: String }) var webComponentSchema = componentSchema.extend({ page: { type: ObjectId, ref: 'Page' } , selector: { type: ObjectId, ref: 'Selector' } }) var pageSchema = new Schema({ name: String , desc: String , url: String , active: { type: Boolean, default: false } , webComponents: [{ type: ObjectId, ref: 'WebComponent' }] }) var selectorSchema = new Schema({ desc: String , url: String , cssPath: String }) ///MODELS var Mashup = db.model("Mashup", mashupSchema) var Component = db.model("Component", componentSchema) var ImageComponent = db.model("ImageComponent", imageComponentSchema) var TextComponent = db.model("TextComponent", textComponentSchema) var HtmlComponent = db.model("HtmlComponent", htmlComponentSchema) var WebComponent = db.model("WebComponent", webComponentSchema) var Page = db.model("Page", pageSchema) var Selector = db.model("Selector", selectorSchema) //CREATE //a new empty mashup //var aMashup = new Mashup({ name: "Test" }); Mashup.create({ name: "Test" }, function (err, mashup) { if (err) return console.log("Saved: empty mashup") //mashup saved, create a webComponent var aWebComponent = new WebComponent({ name: "Map", desc: "A map" }) //create a page var aPage = new Page({ name: "Maps", desc: "Google Maps", url: "http://maps.google.com" }) aPage.webComponents.push(aWebComponent) aWebComponent.page = aPage //create a selector var aSelector = new Selector({desc: "Just the map", url: "maps.google.com", cssPath: "#map" }) aWebComponent.selector = aSelector //save the component aWebComponent.save(function(err) { if (err) return console.log("Saved: WebComponent") aPage.save(function(err) { if (err) return console.log("Saved: the Page") aSelector.save(function(err) { if (err) return console.log("Saved: the Selector") //finally add the item with the new component var item = { pos: { top:6, left:10 }, size: { width:100, height:100}, component: aWebComponent } mashup.items.push(item) mashup.save(function (err) { if (err) return console.log("Saved: mashup with item (WebComponent with Page and Selector)") //POPULATE Mashup .find({}) .populate("items.component") .exec(function (err, mashup) { if (err) console.log(err) console.log(mashup); }) }) }) }) }) }) }); 

这是一个用例场景,用户创build一个Mashup,然后通过创build一个新的WebComponent为其添加一个新的Item。 我需要Item类,因为每个不同的mashup应该能够拥有现有组件的“实例”(即Items)。

现在,我是新来的mongoose,我相信可以做不同的事情。 任何build议在这里都是受欢迎的。 但是,当我尝试查询填充结果的Mashups时,我得到的输出是:

 Saved: empty mashup Saved: WebComponent Saved: the Page Saved: the Selector Saved: mashup with item (WebComponent with Page and Selector) [ { __v: 1, _id: 520a8aae3c1052f723000002, name: 'Test', items: [ { component: null, _id: 520a8aaf3c1052f723000006, size: [Object], pos: [Object] } ], size: {} } ] 

component应该被填充,但不是。 我想这是因为它期望一个Component而它得到一个WebComponent 。 我该如何解决? 我应该停止尝试inheritance? 还有什么其他的方式来为这个模型创build一个数据库模式?

Do ..改变

  var componentSchema = new Schema({ name: String , desc: String }, { discriminatorKey : '_type' }) 

  var componentSchema = new Schema({ name: String , desc: String }, { collection : 'components', discriminatorKey : '_type' }) 

解决了这个问题。 不知道为什么。