【发布时间】:2017-07-25 02:59:39
【问题描述】:
我正在尝试使用 MongoDB 制作电影院的预订系统。
我将有关电影的所有信息保存在模型Movie 中,包括title、description、actors、rating、director 等。
但是,一部电影可以在不同的房间和不同的日期在电影院放映,所以我还有一个模型Showtime,我有room、price和date。
最后,我还需要一个模型Ticket,其中包含purchasedBy、purchasedAt、isRedeemed等字段。
但是,我不知道如何链接模型并提取放映时间。我想在首页上列出所有电影(带有标题、描述和图像),但我也想显示日期和价格。问题是日期和价格可能会有所不同,因为每部电影可以有多个(和不同的)日期和价格,所以我只想显示最小的价格和最快的日期。
目前,我有一个看起来像这样的架构
movieSchema = Schema({
name: String,
description: String,
image: String,
showtimes: [{ type: ObjectId, ref: 'Showtime' }]
});
我只需获取放映时间数组中的第一个放映时间就可以得到日期和价格
Movie.find().populate('showtimes').then(movies => {
movies.forEach(movie => {
console.log(movie.showtimes[0].date)
console.log(movie.showtimes[0].price)
});
});
但是,我需要按最近日期和/或最低价格进行排序,所以我不确定我的数据结构是否适合此目的。
理想的情况是能够做这样的事情:
Movie.find().sort('showtimes.date showtimes.price').populate('showtimes').then(movies => {
...
});
但由于我只将放映时间的 ID 存储在我的 showtimes 字段中,因此这是不可能的。
或者,我可以将架构更改为
showtimeSchema = Schema({
date: Date,
price: Number
});
movieSchema = Schema({
name: String,
description: String,
image: String,
showtimes: [showtimeSchema]
});
所以我不必使用populate()。但是,问题是当客户购买门票时,我需要在门票对象中引用放映时间,因此我需要自己的放映时间模型。
编辑
正如 cmets 中提到的,将文档直接嵌入到 movieSchema 中可能很聪明。但是,我不知道我的Ticket 模型应该是什么样子。
现在是这样的
ticketSchema = Schema({
showtime: { type: ObjectId, ref: 'Showtime' }
purchasedAt: Date,
purchasedBy: { type: ObjectId, ref: 'User' }
isRedeemed: Boolean
})
所以当我打印票时,我必须做类似的事情
Ticket.findById(ticketId).populate({
path: 'Showtime',
populate: {
path: 'Movie'
}
}).then(ticket => {
console.log(ticket.date);
console.log(ticket.event.name);
});
【问题讨论】:
-
如果您确实需要以这种方式查询,那么嵌入是您的最佳选择。
.populate()所做的只是向 MongoDB 发出另一个查询,以便从另一个集合中获取其他信息。在现代 MongoDB 版本中,它实际上基本上被$lookup取代,因为它实际上只是为了“模拟”连接而创建的,而$lookup“实际上是”连接。但尽管如此,“加入”在性能方面是错误的,因此您实际上应该将“相关”数据保留在同一个文档中。 -
之所以是“评论”,是因为您的问题接近征求意见或通常过于宽泛。所以实际上以现在直接征求意见的方式编辑它,或者基本上“扩大主题”对你没有任何好处。也许您实际上有A New Question 或确实有几个,以便找出您需要理解的与一个或另一个用例相关的概念。这样,您可能会比从“一个大问题”中获得更多信息。
标签: javascript mongodb mongoose mongoose-schema mongoose-populate