Reputation:
I have a restaurant idea, that will have branches and every branch has a menu, and every menu has items with there specified price for this branch!
and my schema is:
var mongoose = require('mongoose');
var eaterySchema = mongoose.Schema({
name: String,
type: Number,
branches: [{type: Schema.Types.ObjectId, ref: 'Branch' }]
});
var branchSchema = mongoose.Schema({
id: Number,
name: String,
eatery: {type: Schema.Types.ObjectId, ref: 'Eatery'},
menu: {type: Schema.Types.ObjectId, ref: 'Menu'}
});
var menuSchema = mongoose.Schema({
branch: {type: Schema.Types.ObjectId, ref: 'Branch'},
items: [{type: Schema.Types.ObjectId, ref: 'Item'}]
});
var itemSchema = mongoose.Schema({
name: String,
description: String
});
var itemMenuSchema = mongoose.Schema({ //Many-To-Many Table
menu: {type: Schema.Types.ObjectId, ref: 'Menu'},
item: {type: Schema.Types.ObjectId, ref: 'Item'},
price: Number
});
var Eatery = mongoose.model('Eatery', eaterySchema);
var Branch = mongoose.model('Branch', branchSchema);
var Menu = mongoose.model('Menu', menuSchema);
var Item = mongoose.model('Item', itemSchema);
var ItemMenu = mongoose.model('ItemMenu', itemMenuSchema);
Does the query below written right to get the menu with the items and the item price for requested branch id ?
Branch
.findOne({id: '@GivenId'})
.populate('eatery menu')
.exec(function(err, doc){
doc
.populate('menu.items')
.exec(function(err, doc){
ItemMenu
.find({})
.where('menu._id').equals(doc.menu._id)
.exec(function(err, items){
doc.push(items);
res.send(docs);
})
})
};)
});
and does mongoose provides populate to deal with the last query that I have written in the last callback? and what the better solution to deal with this complex relation?
thanks a lot
Upvotes: 1
Views: 433
Reputation: 256
This schema is a bit too relational, and that query will be much slower than it needs to be. To get the most out of MongoDB, I'd recommend getting rid of ItemMenu entirely: since each menu has a list of items, its redundant, you can just store the corresponding price in Menu's list of items.
Furthermore, you may consider inlining items into each menu, and/or inlining menu into the branch document. This will make your query much simpler and much faster.
Generally, when designing a MongoDB schema, you want to structure your objects so its easy to answer your most common questions. This often means inlining one-to-one or one-to-few relationships. Don't get stuck in a relational mindset - trying to structure MongoDB documents like you would SQL rows is a surefire way to make your life more difficult than it has to be :)
Upvotes: 1