用于预订房间的 MongoDB 架构应该是啥?

Posted

技术标签:

【中文标题】用于预订房间的 MongoDB 架构应该是啥?【英文标题】:What should be my MongoDB schema for room booking?用于预订房间的 MongoDB 架构应该是什么? 【发布时间】:2022-01-02 01:25:29 【问题描述】:

我正在 nodejs 中构建房间预订系统。目前我有 hotelsroomsbookings 作为集合。

rooms 引用 hotelsbookings 引用 rooms

booking.js

const bookingSchema = new mongoose.Schema(
    room: 
        type: mongoose.Schema.Types.ObjectId,
        ref: 'rooms'
    ,
    start: Date,
    end: Date

);

rooms.js

const roomSchema = new mongoose.Schema(
    roomid: String,
    hotel: 
        type: mongoose.Schema.Types.ObjectId,
        ref: 'hotel_managers'
    ,
    type: String,
    price: Number,
    capacity: Number,
    facilities: [String],
    amenities: [String],
    img: [String]

);

hotels.js

const hotel_manager_schema = new mongoose.Schema(
    username: 
        type: String,
        required: true,
        unique: true
    ,
    password: 
        type: String,
        required: true
    ,
    hotelname: 
        type: String,
        required: true
    ,
    role: 
        type: String,
        default: 'manager'
    ,
    location: 
        type: String,
        required: true
    ,
    img:
        type: String,
        required: true
    
)

注意这是一个服务提供商端的系统,因此酒店基本上是具有其凭据的酒店经理。

我想要实现的是,当用户发送给定日期范围的查询时,我想返回所有可用的酒店以及在查询日期范围内没有任何预订的酒店中的房间。

我是 MongoDB 的新手,所以任何关于如何做我想做的事的提示或建议都会有很大帮助。

【问题讨论】:

【参考方案1】:

我希望您的数据库已经积累了一些数据,并且考虑到您所要做的只是在您的 bookingSchema 中进行查询。

    const availableRoom = await Booking.find( //query today up to tonight
    created_on: 
        $gte: new Date(2012, 7, 14), 
        $lt: new Date(2012, 7, 15)
    
)

这里 Booking 是一个模型。您可以在HERE上找到如何创建模型的详细信息

你可以找到HERE如何使用日期查询

【讨论】:

现有预订条目将始终具有日期类型的开始和结束值。我想根据当前预订退回新日期范围内的可用客房。我已经知道日期查询,但我无法使用关系模式。【参考方案2】:

根据您的架构模型架构,您可以执行以下操作;我们想列出在给定日期范围内没有任何预订的所有可用酒店以及酒店中的客房。

因此,为了实现这一点,我们将获取与查询中提供的日期范围重叠的所有预订并返回其房间 ID;之后,我们获取所有房间,不包括从预订返回的房间 ID 数组。

const bookings = await Booking
      .find(
          $or: [
               start:  $gte: from_date, $lte: to_date  ,
              
                  end:  $gte: from_date, $lte: to_date 
              ,
              
                  $and: [ start:  $lte: from_date  ,  end:  $gte: to_date  ]
              ,
          ],
      )
      .select('room');

const roomIds = bookings.map(b => b.room);

const availableRooms = await Room.find( _id:  $nin: roomIds  )

您可以通过填充 Rooms 酒店属性字段来提取酒店的数据:

const availableRooms = await Room
  .find( _id:  $nin: roomIds  )
  .populate('hotel', 'username password hotelname role location img')

我希望这对你有用。

【讨论】:

我按照您的说明进行了尝试,但由于某种原因,即使我查询的日期范围不与任何预订相交,它也会在第一个查询中返回所有当前预订。如果它返回所有预订,根据查询它不应该返回任何与预订相关的房间,但令人惊讶的是它返回包含预订的房间。我一定做错了什么,但我不确定是什么。 我做了一些更改,检查一下,我相信这应该可以。 感谢它的工作,非常感谢您在预订重叠逻辑上的努力。 PS:bookings 集合越大,您的请求查询就越慢,如果我们谈论 500000 或更多文档,您会感觉到不同;所以尝试删除旧的预订文档或将它们存档,并尝试索引房间属性字段,并在获取预订时仅选择房间字段,这样会有所帮助。 是的,我想我可能会运行计划任务来删除较旧的预订,感谢您的提示,我会记住这些。

以上是关于用于预订房间的 MongoDB 架构应该是啥?的主要内容,如果未能解决你的问题,请参考以下文章

用于预订、嵌套或引用的 MongoDB 模式?

用于预订、嵌套或引用的 MongoDB 模式?

如何在 Django 中检查或设置房间可用性

多房间预订的数据库设计:一对多

如何在已使用 sql 预订的预订房间列表中获得空闲时间

设计一个高性能的酒店房间预订系统