[英]Mongodb/mongoose query for completely overlapping dates (that could span multiple documents)
我在設計處理重疊日期的查詢時遇到了一些問題。
所以這是場景,我不能透露太多關於實際項目的信息,但這里有一個類似的例子。 假設我有一個FleaMarket
。 它有一堆關於它自己的數據,比如name
、 location
等。
因此,一個FleaMarket
將有許多Stalls
,可用來預訂全年的一部分(如短至2天,只要全年的那種東西)。 因此, FleaMarket
需要指定一年內的開放時間。 大多數場景要么全年開放,要么整個夏季/秋季開放,但可能會進一步細分(因為季節決定定價)。 每個FleaMarket
將定義自己的Seasons
,其中將包括一個startDate
和endDate
(含一年)。
這是一個用於建模此示例的 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.