我有一个餐厅的想法,将有分支机构,每个分支都有一个菜单,每个菜单都有这个分支的指定价格的项目!
我的架构是:
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来处理我在上一次回调中写的最后一个查询?什么是处理这种复杂关系的更好的解决方案?
非常感谢
答案 0 :(得分:2)
这个架构有点过于关系,而且查询速度会慢得多。为了充分利用MongoDB,我建议完全摆脱ItemMenu:因为每个菜单都有一个项目列表,它是多余的,你可以在菜单的项目列表中存储相应的价格。
此外,您可以考虑将项目内联到每个菜单中,和/或将内联菜单内嵌到分支文档中。这将使您的查询更简单,更快。
通常,在设计MongoDB架构时,您需要构建对象,以便轻松回答最常见的问题。这通常意味着内联一对一或一对一的关系。不要陷入关系心态 - 尝试构建MongoDB文档,就像SQL行一样,这是一种让你的生活更加困难的绝对方式:)