次のモデルのデータベース スキーマを作成しようとしています。
MongoDb でこれを表現するより良い方法はわかりませんが、Mongoose を使用しており、継承用のプラグインがあるため、次のことを試しています。
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);
})
})
})
})
})
})
});
これは、ユーザーがマッシュアップを作成し、新しい WebComponent を作成して新しいアイテムをそれに追加するユース ケース シナリオです。それぞれの異なるマッシュアップが既存のコンポーネントの「インスタンス」(つまりアイテム) を持つことができる必要があるため、その Item クラスが必要です。
今、私はマングースに不慣れであり、物事は別の方法で行うことができると確信しています. ここでの提案は大歓迎です。ただし、結果を入力するマッシュアップをクエリしようとすると、次のような出力が得られます。
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
ます。これを修正するにはどうすればよいですか? 継承をやめるべきですか?このモデルの DB スキーマを作成するには、他にどのような方法がありますか?