Reputation: 3675
Here is my schema:
var A = new Schema({
active: Boolean
, containers: [{
b: { type: ObjectId, ref: 'B' }
}]
})
var B = new Schema({
c: { type: ObjectId, ref: 'C' }
, d: { type: ObjectId, ref: 'D' }
})
var C = new Schema({ })
var D = new Schema({ })
Basically an A
has an array of containers that have a reference to a B
, and a B
has a reference to a C
and a D
.
Now I have the id of a C
and I need a set of D
that are used by active
A
s. Is this even possible? Should I change the schema in some way?
EDIT: real schema here
//Mashup has a number of Containers (containerSchema is a sub-doc)
//so that the same Component could belong to two different Containers
var containerSchema = 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 }
, active: Boolean
, containers: [containerSchema]
})
//I am using 'mongoose-schema-extend' to inherit from componentSchema (waiting for the new PR)
var componentSchema = new Schema({
name: String
, desc: String
}, { collection : 'components', discriminatorKey : '_type' })
//now the various components
var imageComponentSchema = componentSchema.extend({
url: String
})
var textComponentSchema = componentSchema.extend({
text: String
})
var htmlComponentSchema = componentSchema.extend({
html: String
})
//this particular component needs a page and a selector
//(which could live outside it and belong to multiple components)
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 }
})
var selectorSchema = new Schema({
desc: String
, url: String
, cssPath: String
})
///MODELS
var Mashup = mongoose.model("Mashup", mashupSchema)
var Component = mongoose.model("Component", componentSchema)
var ImageComponent = mongoose.model("ImageComponent", imageComponentSchema)
var TextComponent = mongoose.model("TextComponent", textComponentSchema)
var HtmlComponent = mongoose.model("HtmlComponent", htmlComponentSchema)
var WebComponent = mongoose.model("WebComponent", webComponentSchema)
var Page = mongoose.model("Page", pageSchema)
var Selector = mongoose.model("Selector", selectorSchema)
Upvotes: 0
Views: 128
Reputation: 36774
You think too relational! Right now you, I don't think you can do this efficiently as you will have to:
c: {id}
b
that is the set of the result from query 1 and are ActiveI think you should most definitely denormalise your schema here. For example, you can put all of the above in one document:
{
Active: true,
containers: [ // B's
{ c: [
{ _id: X, field1: foo },
{ _id: X, field1: foo },
] },
{ d: [
{ _id: X, field1: foo },
{ _id: X, field1: foo },
] }
]
}
And then you can just do it with one query:
db.collection.find(
{ "container.c._id" : your_id, Active: true }, // query
{ "container.d" : 1 } // projection
);
Upvotes: 1