我将 MongoDb 与 Mongoskin 一起使用。在一个集合中,我正在保存事件。在其他字段中,这些事件有一个开始和结束,保存Dates
在 Mongodb 中。
events {
start: "Date1",
end: "Date2",
...
}
在此集合中插入新文档时,我需要一个约束来禁止插入开始日期与已创建事件重叠的文档。简而言之,我不希望任何事件共享相同的时间跨度。
问题:有没有办法通过带有某种唯一索引的 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 运算符。
编辑
更新 (PUT) 事件时会出现问题。我不能重用上面的代码,因为它依赖于upsert
and $setOnInsert
。
编辑
@wdberkeley:
我仍在努力解决这个主要问题:确保 range 的唯一性。我想得越多,似乎“时间片数组”可能是最没有问题的解决方案。例如,假设选择 5 分钟作为最短时间段,平均预订时间为 45 分钟。这将需要我保存 9 个数字(可能是date
s)timespan = [0,5,10,15,20,25,30,35,40]
:,而不是两个:start=0, end=45
。这是平均预订数据的四倍多。我并不是要严厉,但你不认为这是一个问题吗?还是当保存的数据大10 倍或100 倍时首先成为问题?我确实意识到这也与实际预订的总数量有关......