我使用MongoDb和Mongoskin.在一个集合中,我正在保存事件.
在其他字段中,这些事件具有开始和结束,在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和$setonInsert.
编辑
@wdberkeley:
我仍在努力解决这个主要问题:确保范围内的唯一性.我越是想到它,似乎“时间片阵列”可能是最无问题的解决方案.例如,假设选择5分钟作为最小时间段,平均预订时间为45分钟.这需要我保存9个数字(可能是日期):timespan = [0,5,10,15,20,25,30,35,40],而不是两个:start = 0,end = 45.
这是平均预订数据的四倍以上.
我不是要苛刻,但你不认为这是一个问题吗?或者当保存的数据大10倍或大100倍时,它是否首先成为问题?我确实意识到这也与实际预订的总量有关…
解决方法:
在MongoDB中没有一种简单的方法可以做到这一点.我做了一个可能适合你的替代选择.如果您的日期采用不连续的步骤,例如,如果这是针对用户按日或按小时保留对象的预订应用程序,则可以使用唯一索引和多键索引的组合.例如,假设预订是白天.约翰Q保留10月11日至10月14日(含).这就像是一年中的第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一个锁集合中的文件来检查和获取一个锁.一旦客户端通过更改该文档上的字段来获得锁定,它就可以检查与查询的重叠,然后检查插入是否一切正常,然后通过再次更改锁定文档上的标志来释放锁定.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。