我在MongoDB中使用MongoDb。在一個集合中,我正在保存事件。 在其他字段中,這些事件有一個開始和結束,在Mongodb中保存爲Dates
。MongoDb對日期範圍的唯一約束
events {
start: "Date1",
end: "Date2",
...
}
當這個集合中插入新的文件,我需要禁止的文件插入其開始結束日期重疊alreay創建事件的約束。總之,我不希望任何事件共享相同的時間跨度。
問題:有沒有一種方法可以通過MongoDb處理這種約束,帶有某種唯一索引?我想不是,但如果我錯了,請糾正我!
如果不是:
問題我一定要檢查可能插入新的事件之前,重疊槽代碼?我是否需要設置某種寫鎖定,以便在檢查重疊並插入自己的事件之間,另一個用戶無法擠入事件?這在MongoDb中如何完成?
編輯
這是我想出了迄今爲止最好的方法,它實際上似乎工作不錯。
var input = getPostInput();
var query = {$and: [
{start: {$lte: input.end}},
{end: {$gte: input.start}}
]};
db.events.findAndModify(query, {}, {$setOnInsert: input}, {new: true, upsert: true}, callback)
它使用findAndModify
作爲「findOrCreate」操作符的一種類型。 $setOnInsert
僅當findAndModify
未找到文檔時才添加POST輸入屬性,upsert: true
說如果找不到文檔,它應該創建文檔。這兩個選項組合似乎創建了一個findOrCreate操作符。
EDIT更新時出現
問題(PUT)的事件。我不能重複使用上面的代碼,因爲它依賴於upsert
和$setOnInsert
。
編輯
@wdberkeley:
我還在這個主要問題掙扎:確保在一系列唯一性。我越想它,似乎「時間片陣列」可能是最不成問題的解決方案。例如,假設選擇5分鐘作爲最小時間段,並且平均預訂爲45分鐘。這將需要我保存9個號碼(可能爲date
):timespan = [0,5,10,15,20,25,30,35,40]
,而不是兩個:start=0, end=45
。 這是超過的四倍更多已保存數據平均預訂成功。 我不認爲是苛刻的,但你不覺得這是一個問題?或者當保存的數據是10次較大或100次較大時是否成爲問題?我意識到這也是相對於實際完成的預訂量的總和......
感謝您的回覆!請閱讀我對上述問題的編輯,看看我的解決方案是否是您最後一段中的意思。關於「鎖」,我不知道這意味着什麼,但是正如我所理解的,這個'findAndModify'將會被atomicaly完成,因此會「鎖定」這個集合,以便其他用戶不會在查詢和更新階段之間發生事件。 findAndModify操作。正確? – 2014-09-29 07:50:49
可以說我把整個集合放在一個鎖上,而第二個用戶在第一個用戶擁有這個鎖的時候試圖保存一個事件。我應該如何迴應第二個用戶的嘗試?有錯誤信息? – 2014-09-29 09:32:54
如果您要創建一個已創建的事件,那麼解決方案有什麼問題?我以爲你不想讓重疊?你也可以有一個單獨的更新路線。你可能會有第二個用戶的鎖重試循環,但我認爲你的更簡單的解決方案應該工作,所以它並不重要。 – wdberkeley 2014-09-29 14:52:11