猫鼬的复杂关系

时间:2014-10-24 17:43:45

标签: node.js mongodb mongoose

我有一个餐厅的想法,将有分支机构,每个分支都有一个菜单,每个菜单都有这个分支的指定价格的项目!

我的架构是:

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

下面的查询是否正确获取包含所请求分支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);
            })
        })
    };)
});

并且mongoose是否提供了populate来处理我在上一次回调中写的最后一个查询?什么是处理这种复杂关系的更好的解决方案?

非常感谢

1 个答案:

答案 0 :(得分:2)

这个架构有点过于关系,而且查询速度会慢得多。为了充分利用MongoDB,我建议完全摆脱ItemMenu:因为每个菜单都有一个项目列表,它是多余的,你可以在菜单的项目列表中存储相应的价格。

此外,您可以考虑将项目内联到每个菜单中,和/或将内联菜单内嵌到分支文档中。这将使您的查询更简单,更快。

通常,在设计MongoDB架构时,您需要构建对象,以便轻松回答最常见的问题。这通常意味着内联一对一或一对一的关系。不要陷入关系心态 - 尝试构建MongoDB文档,就像SQL行一样,这是一种让你的生活更加困难的绝对方式:)