user3482773
user3482773

Reputation:

Complex Relation in Mongoose

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

Answers (1)

Valeri Karpov
Valeri Karpov

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

Related Questions