首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MongoDB中电影售票系统的数据结构

MongoDB中电影售票系统的数据结构
EN

Stack Overflow用户
提问于 2017-07-23 06:56:18
回答 1查看 1.6K关注 0票数 1

我正试图与MongoDB一起为一家电影院建立一个预订系统。

我把关于电影的所有信息都保存在模型Movie中,包括titledescriptionactorsratingdirector等等。

然而,电影可以在不同的房间和不同的日期在电影院放映,所以我也有一个模型Showtime,在那里我有roompricedate

最后,我还需要一个模型Ticket与字段purchasedBypurchasedAtisRedeemed等。

然而,我不知道如何链接模型和提取显示时间。我想在首页上列出所有的电影(有标题,描述和图像),但我也想显示日期和价格。问题是,日期和价格可能会有所不同,因为每部电影都有多个日期和价格,所以我只想显示最小的价格和最快的日期。

目前,我有一个类似于

代码语言:javascript
复制
movieSchema = Schema({
  name: String,
  description: String,
  image: String,
  showtimes: [{ type: ObjectId, ref: 'Showtime' }]
});

我可以通过在展示时间数组中获取第一次展示时间来获得一个日期和价格。

代码语言:javascript
复制
Movie.find().populate('showtimes').then(movies => {
  movies.forEach(movie => {
    console.log(movie.showtimes[0].date)
    console.log(movie.showtimes[0].price)
  });
});

但是,我需要按最近的日期和/或最低的价格进行排序,所以我不确定我的数据结构是否适合这个目的。

最理想的是能够做这样的事情:

代码语言:javascript
复制
Movie.find().sort('showtimes.date showtimes.price').populate('showtimes').then(movies => {
  ...
});

但是,由于我只将显示时间的in存储在我的showtimes字段中,所以这是不可能的。

或者,我可以将模式更改为

代码语言:javascript
复制
showtimeSchema = Schema({
  date: Date,
  price: Number
});

movieSchema = Schema({
  name: String,
  description: String,
  image: String,
  showtimes: [showtimeSchema]
});

所以我不需要使用populate()。然而,问题是,当客户购买一张票时,我需要引用票证对象中的显示时间,所以我需要一个单独的展示时间模型。

编辑

正如注释中提到的,将文档直接嵌入到movieSchema中可能是明智的。但是,我不知道我的Ticket模型应该是什么样子。

现在有点像

代码语言:javascript
复制
ticketSchema = Schema({
  showtime: { type: ObjectId, ref: 'Showtime' }
  purchasedAt: Date,
  purchasedBy: { type: ObjectId, ref: 'User' }
  isRedeemed: Boolean
})

所以当我印票的时候,我得做一些事情

代码语言:javascript
复制
Ticket.findById(ticketId).populate({
  path: 'Showtime',
  populate: {
    path: 'Movie'
  }
}).then(ticket => {
  console.log(ticket.date);
  console.log(ticket.event.name);
});
EN

回答 1

Stack Overflow用户

发布于 2017-07-23 07:07:59

我将使用您的第二个模式;为显示时间创建一个新的模型/集合是没有意义的,因为您不会在展示时间进行事务处理,而是在访问者、电影和门票上进行事务处理。看起来是这样的:

代码语言:javascript
复制
movieSchema = Schema({
  name: String,
  description: String,
  image: String,
  showtimes: [{
    date: Date,
    price: Number
  }]
});

然后,您可以做的是按数组的最小/最大值排序。所以看起来是这样的:

代码语言:javascript
复制
Movie.find().sort({'name.showtimes.date' : -1, price: 1})

这需要每部电影的最新放映时间,并按时间排序(以及最低的价格)。

编辑:

您可以在票证中引用电影,并将放映时间存储在那里:

代码语言:javascript
复制
ticketSchema = Schema({
  showtime: Date,
  purchasedAt: Date,
  purchasedBy: { type: ObjectId, ref: 'User' }
  isRedeemed: Boolean,
  movie: { type: ObjectId, ref: 'Movie' }
})

如果您由于任何原因需要更多的结构,我会考虑使用SQL。嵌套填充(本质上是SQL连接)是维护/优化的噩梦,RDBMS更适合这样的数据。

编辑2:

好吧,让我们在这里权衡一下我们的选择。你是对的,如果一个时间/地点改变,你将不得不更新所有的门票。因此,单独存储显示时间给我们带来了好处。另一方面,这给您查找的几乎每一张票证都增加了一层复杂性,更不用说性能损害和服务器成本了。即使票务/地点变更频繁发生,我也几乎肯定您的票务查询更加频繁。

尽管如此,我认为这里的一个好方法是在显示时间下存储一个_id,然后以这种方式查找您的票:

代码语言:javascript
复制
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,以便通过显示时_id轻松查找。

代码语言:javascript
复制
Movie.findByShowtime('some showtime id').exec()

当你拿了电影后,你可以像这样抓住放映时间:

代码语言:javascript
复制
var st = movie.showtimes.id('some showtime id');

关于分文件的进一步阅读。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45262364

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档