我正在尝试使用MongoDB制作影院预订系统。
我会在模型Movie
中保留有关该电影的所有信息,包括title
,description
,actors
,rating
,director
等等。
但是,电影可以在不同房间和不同日期的电影院中播放,因此我还有一个模型Showtime
,其中我有room
,price
和{ {1}}。
最后,我还需要一个模型date
,其中包含字段Ticket
,purchasedBy
,purchasedAt
等。
但是,我不知道如何链接模型并提取放映时间。我想在首页上列出所有电影(包括标题,描述和图像),但我也想显示日期和价格。问题是日期和价格可能会有所不同,因为每部电影可能有多个(和不同的)日期和价格,所以我只想显示最小的价格和最快的日期。
目前,我的模式看起来像
isRedeemed
我可以通过在放映时间阵列中第一个showtime获得日期和价格
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]
});
。但问题是,当客户购买票证时,我需要在票证对象中引用showtime,因此我需要一个自己的放映时间模型。
正如评论中所提到的,将文档直接嵌入populate()
可能很聪明。但是,我不知道我的movieSchema
模型应该是什么样的。
现在它就像是
Ticket
因此,当我打印机票时,我必须做类似
的事情ticketSchema = Schema({
showtime: { type: ObjectId, ref: 'Showtime' }
purchasedAt: Date,
purchasedBy: { type: ObjectId, ref: 'User' }
isRedeemed: Boolean
})
答案 0 :(得分:0)
我会使用你的第二个架构;因为您不会在showtime上进行交易,而是在访客,电影和门票上进行交易,因此在为放映时间创建新模型/集合时没有任何意义。所以看起来像这样:
movieSchema = Schema({
name: String,
description: String,
image: String,
showtimes: [{
date: Date,
price: Number
}]
});
然后,你可以做的是sort by the min/max values of the array。所以这看起来像这样:
Movie.find().sort({'name.showtimes.date' : -1, price: 1})
这会拍摄每部电影的最新放映时间(以及最低价格)。
你可以在故障单中引用电影,并在那里存储showtime:
ticketSchema = Schema({
showtime: Date,
purchasedAt: Date,
purchasedBy: { type: ObjectId, ref: 'User' }
isRedeemed: Boolean,
movie: { type: ObjectId, ref: 'Movie' }
})
如果由于某种原因需要更多的结构,我会考虑使用SQL代替。嵌套填充(实际上是SQL JOIN)是维护/优化的噩梦,而RDBMS更适合这样的数据。
好的,让我们在这里权衡我们的选择。你是对的,如果时间/场地发生变化,你必须更新所有门票。因此,单独存储showtime给我们带来了好处。另一方面,这为您查找的虚拟每个票证增加了一层复杂性,更不用说性能损失和增加的服务器成本。即使票房/场地频繁发生变化,我也非常肯定您的票证查询频率更高。
话虽这么说,我认为这里的一个好方法是在showtime子项目上存储_id
,并以这种方式查找你的门票:
showtimeSchema = Schema({
date: Date,
price: Number
});
movieSchema = Schema({
name: String,
description: String,
image: String,
// When you use a sub-schema like this, mongoose creates
// an `_id` for your objects.
showtimes: [showtimeSchema]
});
// Now you can search movies by showtime `_id`.
Movie.find({showtimes: 'some showtime id'}).exec()
您可以更进一步,在Movie
模型上注册static,以便通过showtime _id
轻松查找:
Movie.findByShowtime('some showtime id').exec()
当你拍摄电影时,你可以像这样抓住showtime:
var st = movie.showtimes.id('some showtime id');