Fill with an inherited document in Mongoose

I am trying to create a database schema for the following model:

enter image description here

I'm not sure if the best way to represent this in MongoDb would be, but since I'm using Mongoose and there is a plugin for inheritance, I'm trying to do the following:

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

This is a use case when a user creates a Mashup and then adds a new element to it, creating a new WebComponent. I need this Item class because every other mashup must have β€œinstances” (i.e. Elements) of existing Components.

Now I'm new to Mongoose, and I'm sure everything can be done differently. Any suggestion is welcome here. However, when I try to request filling in Mashups, the result I get is the following:

 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 must be populated, but it is not. I think this is because it expects a component while it receives a WebComponent . How to fix it? Should I stop trying with inheritance? What other methods exist for creating a database schema for this model?

+1
source share
1 answer

Doh .. change

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

to

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

Fixes a problem. I do not know why.

+1
source

Source: https://habr.com/ru/post/959495/


All Articles