MongoDb对日期范围的唯一约束
MongoDb unique constraints on a Date range
Im使用MongoDb和Mongoskin。在集合中,我正在保存事件。在其他字段中,这些事件有一个开始和一个结束,在Mongodb中保存为Dates
。
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"运算符。只有当findAndModify
找不到文档时,$setOnInsert
才会添加POST输入属性,而upsert: true
表示,如果找不到,它应该创建一个文档。这两个选项的组合似乎创建了一个findOrCreate运算符。
编辑
更新(PUT)事件时会出现问题。我不能重用上面的代码,因为它依赖于upsert
和$setOnInsert
。
编辑
@wdberkeley:
我仍在努力解决这个主要问题:确保范围内的唯一性。我想得越多,似乎"时间片数组"可能是最没有问题的解决方案。例如,假设选择5分钟作为最小时间段,平均预订时间为45分钟。这将需要我保存9个数字(可能是date
s):timespan = [0,5,10,15,20,25,30,35,40]
,而不是两个:start=0, end=45
。这是平均预订保存数据的四倍多。我无意苛刻,但你不认为这是个问题吗?或者,当保存的数据是10倍大还是100倍大时,它首先会成为问题?我确实意识到,这也是相对于实际预订的总数量。。。
在MongoDB中没有一种非常简单的方法可以做到这一点。我想出了一个对你有用的替代方案。如果你的日期是离散的,比如这是一个预订应用程序,用户按天或小时预订对象,那么你可以使用唯一索引和多关键字索引的组合。例如,假设预订是按天进行的。John Q保留10月11日至10月14日(含10月11至10月)。这有点像一年中的第281天到第284天-让我们假设这正是哪几天。将保留字段保存为保留的天数数组
> db.reservations.insert({ "span" : [ 281, 282, 283, 284 ] })
在span
字段上设置一个唯一索引。
> db.reservations.ensureIndex({ "span" : 1}, { "unique" : 1 })
现在你不能插入一个在其跨度内有任何一天的文档:
> db.reservations.insert({ "span" : [ 279, 280, 281, 282 ] })
// unique key error
考虑到年份,这可能会对您进行一些额外的调整,或者它可能是复合唯一索引的一部分,以使时间跨度具有唯一性,例如酒店预订的room_id
。
另一种方法是协调客户端的检查。如果你有多个客户端根本不相互交谈,我想最好的方法是在数据库中共享一个"锁":findAndModify
是lock
集合中的一个文档,用于检查和获取锁。一旦客户端通过更改文档上的字段获得锁定,它就可以检查与查询的重叠,然后在一切正常的情况下插入,然后通过再次更改锁定文档上的标志来释放锁定。
- 使用onkeyup JS事件检查输入的值是否唯一
- 当同一浏览器的两个实例浏览时,Javascript页面如何具有唯一的ID
- Lodash映射并返回唯一
- 在数据库中循环值时,为输入框获取唯一值
- 如何从数组中查找唯一对象
- 正在为循环创建唯一id
- 获取唯一值并使用javascript计算金额总和
- JavaScript:从对象数组中获取唯一值及其计数
- ng重复中的ng模型-初始化唯一作用域属性
- 生成唯一的ids js
- 创建具有2个唯一数字的Javascript数组
- 对中的函数调用进行排序是回调的唯一方法
- 如何在传单.js中显示每个choropleth弹出窗口的唯一名称和URL
- 在JavaScript中创建全局唯一ID
- 对续集列的唯一约束
- 唯一字段约束在 dropDatabase 之后未强制执行
- Sequelize:无法设置新的唯一约束消息
- MongoDb对日期范围的唯一约束
- 生成具有最大长度约束的唯一id的Uuid替代方案
- 唯一约束JayData