簡體   English   中英

Mongodb/mongoose 查詢完全重疊的日期(可以跨越多個文檔)

[英]Mongodb/mongoose query for completely overlapping dates (that could span multiple documents)

我在設計處理重疊日期的查詢時遇到了一些問題。

所以這是場景,我不能透露太多關於實際項目的信息,但這里有一個類似的例子。 假設我有一個FleaMarket 它有一堆關於它自己的數據,比如namelocation等。

因此,一個FleaMarket將有許多Stalls ,可用來預訂全年的一部分(如短至2天,只要全年的那種東西)。 因此, FleaMarket需要指定一年內的開放時間。 大多數場景要么全年開放,要么整個夏季/秋季開放,但可能會進一步細分(因為季節決定定價)。 每個FleaMarket將定義自己的Seasons ,其中將包括一個startDateendDate (含一年)。

這是一個用於建模此示例的 ERD:

在此處輸入圖片說明

當用戶嘗試預訂Stall ,他們已經選擇了FleaMarket (盡管理想情況下,根據未來的可用性進行搜索會很好)。 很容易判斷是否已在要求的日期預訂了Stall

bookings = await Booking.find({
  startDate: { $lt: <requested end date> },
  endDate: { $gt: <requested start date> },
  fleaMarketId: <flea market id>,
}).select('stallId');
bookedIds = bookings.map(b => b.stallId);

stalls = await Stall.find({
  fleaMarketId: <flea marked id>,
  _id: { $nin: bookedIds }
});

我遇到的問題是確定是否有Stall可用於指定的Season 問題是 2 個季節可能是連續的,因此您可以進行跨 2 個季節的預訂。

我最初嘗試過這樣的查詢:

seasons = await Season.find({
  fleaMarketId: <flea market id>,
  startDate: { $lt: <requested end date> },
  endDate: {$gt: <requested start date> }
});

然后以編程方式檢查任何返回的季節是否是連續的,並從所有季節都存在的攤位中挑選可用的攤位。 但不幸的是,我剛剛意識到如果請求的日期僅與一個季節部分重疊,這將不起作用(例如:請求Jan 1 2020 - Jan 10 2020 ,但該季節定義為Jan 2 2020 - May 1 2020

有沒有辦法檢查可能與多個文檔重疊的完全重疊的日期? 我正在考慮計算和存儲當前和未來可用的季節日期(存儲為總范圍)在Stall上非規范化。

在這一點上,我幾乎在想我需要對架構進行相當多的重構。 有什么建議嗎? 我知道這看起來非常相關,但應用程序中的其他幾乎所有地方都沒有真正處理這些關系。 正是這種搜索是相當有問題的。

更新

我只是想到可能會創建某種Calendar文檔,可以存儲FleaMarket的集中可用性列表,這將進行滾動更新以僅存儲未來和當前數據,並慢慢擦除歷史數據,或者可能將其存檔以不同的格式。 也許這會解決我的問題,我將很快與我的團隊討論。

因此,正如我在帖子的更新中所說,我想出了創建滾動日歷的想法。

對於任何有興趣的人,這是我得到的:

我創建了一個Availability集合,其中包含如下文檔:

{
  marketId: ObjectId('5dd705c0eeeaf900450e7009'),
  stallId: ObjectId('5dde9fc3bf30e500280f80ce'),
  availableDates: [
    {
      date: '2020-01-01T00:00:00.000Z',
      price: 30.0,
      seasonId: '5dd708e7534f3700a9cad0e7',
    },
    {
      date: '2020-01-02T00:00:00.000Z',
      price: 30.0,
      seasonId: '5dd708e7534f3700a9cad0e7',
    },
    {
      date: '2020-01-03T00:00:00.000Z',
      price: 35.0,
      seasonId: '5dd708e7534f3700a9cad0e8',
    }
  ],
  bookedDuring: [
    '2020-01-01T00:00:00.000Z'
    '2020-01-02T00:00:00.000Z'
  ]
}

然后處理此集合的更新:

四季

  • 創建時,將新日期推到每個攤位上(並刪除過去的日期)
  • 更新時,刪除舊日期並添加新日期(或計算差異,取決於此數據的完整性)
  • 刪除時,刪除日期

攤位

  • 創建時,插入關聯季節的記錄
  • 刪除時,從可用性集合中刪除記錄

預訂

  • 創建時,將日期添加到bookedDuring
  • 更新時,從bookedDuring添加或刪除日期

然后要查找市場的可用攤位,您可以查詢 where { marketId: /* market's ID */, availableDates.date: { $all: [/* each desired day */], bookedDuring: { $nin: [/* same dates */ ] } }}然后取出stallId

要查找可用的市場,請執行{ availableDates.dates: { $all: [/* each desired day */], bookedDuring: { $nin: [/* same dates */ ] } }}選擇不同的marketIds

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM