Javascript MongoDB电影票务系统的数据结构
我正在尝试使用MongoDB为电影院制作预订系统 我将有关电影的所有信息保存在一个模型中,包括Javascript MongoDB电影票务系统的数据结构,javascript,mongodb,mongoose,mongoose-schema,mongoose-populate,Javascript,Mongodb,Mongoose,Mongoose Schema,Mongoose Populate,我正在尝试使用MongoDB为电影院制作预订系统 我将有关电影的所有信息保存在一个模型中,包括标题,描述,演员,评级,导演,等等 然而,电影可以在不同的房间和不同的日期在电影院放映,因此我也有一个模型Showtime,其中我有room、price、和date 最后,我还需要一张带有字段purchasedBy、purchasedAt、isredemed的模型Ticket 但是,我不知道如何链接模型和提取展示时间。我想在frontpage上列出所有电影(包括标题、描述和图片),但我也想显示日期和价格
标题
,描述
,演员
,评级
,导演
,等等
然而,电影可以在不同的房间和不同的日期在电影院放映,因此我也有一个模型Showtime
,其中我有room
、price
、和date
最后,我还需要一张带有字段purchasedBy
、purchasedAt
、isredemed
的模型Ticket
但是,我不知道如何链接模型和提取展示时间。我想在frontpage上列出所有电影(包括标题、描述和图片),但我也想显示日期和价格。问题是日期和价格可能会有所不同,因为每部电影可能有多个(和不同的)日期和价格,所以我只想显示最小的价格和最快的日期
目前,我有一个类似于
movieSchema = Schema({
name: String,
description: String,
image: String,
showtimes: [{ type: ObjectId, ref: 'Showtime' }]
});
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);
});
我可以通过在一系列的showtime中选择第一个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 => {
...
});
Movie.find().sort({'name.showtimes.date' : -1, price: 1})
var st = movie.showtimes.id('some showtime id');
但是,由于我只在我的showtimes
字段中存储showtimes的ID,这是不可能的
或者,我可以将模式更改为
showtimeSchema = Schema({
date: Date,
price: Number
});
movieSchema = Schema({
name: String,
description: String,
image: String,
showtimes: [showtimeSchema]
});
因此,我不必使用populate()
。但是,问题是,当客户购买一张票时,我需要在ticket对象中引用showtime,因此我需要一个showtime模型
编辑
如评论中所述,将文档直接嵌入到movieSchema
中可能是明智之举。但是,我不知道我的车票型号应该是什么样子
现在有点像
movieSchema = Schema({
name: String,
description: String,
image: String,
showtimes: [{ type: ObjectId, ref: 'Showtime' }]
});
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);
});
所以当我在打印票的时候,我必须做一些类似的事情
movieSchema = Schema({
name: String,
description: String,
image: String,
showtimes: [{ type: ObjectId, ref: 'Showtime' }]
});
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);
});
我会使用你的第二个模式;为showtimes创建新的模型/集合是毫无意义的,因为您不会在showtimes上进行交易,而是在访客、电影和门票上进行交易。看起来是这样的:
movieSchema = Schema({
name: String,
description: String,
image: String,
showtimes: [{
date: Date,
price: Number
}]
});
那么,你能做的就是。所以看起来是这样的:
Movie.find().sort('showtimes.date showtimes.price').populate('showtimes').then(movies => {
...
});
Movie.find().sort({'name.showtimes.date' : -1, price: 1})
var st = movie.showtimes.id('some showtime id');
这将获取每部电影的最新放映时间,并按该时间进行排序(以及最低价格)
编辑:
您可以在票证中引用电影,并将放映时间存储在那里:
ticketSchema = Schema({
showtime: Date,
purchasedAt: Date,
purchasedBy: { type: ObjectId, ref: 'User' }
isRedeemed: Boolean,
movie: { type: ObjectId, ref: 'Movie' }
})
如果出于任何原因需要更多的结构,我会考虑使用SQL。嵌套填充(本质上是SQL连接)是维护/优化的噩梦,RDBMS更适合这样的数据
编辑2:
好的,让我们在这里权衡一下我们的选择。你说得对,如果时间/地点发生变化,你必须更新所有门票。因此,单独存储showtime为我们带来了这一好处。另一方面,这实际上给您查找的每一张票证都增加了一层复杂性,更不用说性能损失和增加的服务器成本了。即使门票/场地频繁变动,我几乎可以肯定的是,您的门票查询会更加频繁
话虽如此,我认为这里的一个好方法是在showtime子对象上存储\u 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()
您可以在这里更进一步,在电影
模型上注册,以便通过showtime\u id
轻松查找:
Movie.findByShowtime('some showtime id').exec()
拍摄完电影后,您可以像这样把握放映时间:
Movie.find().sort('showtimes.date showtimes.price').populate('showtimes').then(movies => {
...
});
Movie.find().sort({'name.showtimes.date' : -1, price: 1})
var st = movie.showtimes.id('some showtime id');
我会使用你的第二个模式;为showtimes创建新的模型/集合是毫无意义的,因为您不会在showtimes上进行交易,而是在访客、电影和门票上进行交易。看起来是这样的:
movieSchema = Schema({
name: String,
description: String,
image: String,
showtimes: [{
date: Date,
price: Number
}]
});
那么,你能做的就是。所以看起来是这样的:
Movie.find().sort('showtimes.date showtimes.price').populate('showtimes').then(movies => {
...
});
Movie.find().sort({'name.showtimes.date' : -1, price: 1})
var st = movie.showtimes.id('some showtime id');
这将获取每部电影的最新放映时间,并按该时间进行排序(以及最低价格)
编辑:
您可以在票证中引用电影,并将放映时间存储在那里:
ticketSchema = Schema({
showtime: Date,
purchasedAt: Date,
purchasedBy: { type: ObjectId, ref: 'User' }
isRedeemed: Boolean,
movie: { type: ObjectId, ref: 'Movie' }
})
如果出于任何原因需要更多的结构,我会考虑使用SQL。嵌套填充(本质上是SQL连接)是维护/优化的噩梦,RDBMS更适合这样的数据
编辑2:
好的,让我们在这里权衡一下我们的选择。你说得对,如果时间/地点发生变化,你必须更新所有门票。因此,单独存储showtime为我们带来了这一好处。另一方面,这实际上给您查找的每一张票证都增加了一层复杂性,更不用说性能损失和增加的服务器成本了。即使门票/场地频繁变动,我几乎可以肯定的是,您的门票查询会更加频繁
话虽如此,我认为这里的一个好方法是在showtime子对象上存储\u 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()
您可以在这里更进一步,在电影
模型上注册,以便通过showtime\u id
轻松查找:
Movie.findByShowtime('some showtime id').exec()
拍摄完电影后,您可以像这样把握放映时间:
Movie.find().sort('showtimes.date showtimes.price').populate('showtimes').then(movies => {
...
});
Movie.find().sort({'name.showtimes.date' : -1, price: 1})
var st = movie.showtimes.id('some showtime id');
如果您真的需要用这种方式进行查询,那么嵌入就是一种方式。.populate()
所做的就是向MongoDB发出另一个查询,以便从另一个集合获取其他信息。在现代MongoDB版本中,它基本上被$lookup
取代,因为它实际上只是为了“模拟”一个连接而创建的,而$lookup
实际上是“执行”连接。但是,从性能角度来看,“加入”是错误的,因此您实际上应该将“相关”数据保存在同一文档中。之所以将其作为“评论”,是因为您的问题接近于征求意见或建议