javascript – 日期范围内的MongoDb唯一约束

我使用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一个锁集合中的文件来检查和获取一个锁.一旦客户端通过更改该文档上的字段来获得锁定,它就可以检查与查询的重叠,然后检查插入是否一切正常,然后通过再次更改锁定文档上的标志来释放锁定.

相关文章

MongoTemplate 是Spring Data MongoDB 中的一个核心类,为 S...
笔者今天要分享的是一个项目重构过程中如何将数据库选型由原...
mongodb/mongoTemplate.upsert批量插入更新数据的实现
进入官网下载官网安装点击next勾选同意,点击next点击custom...
头歌 MongoDB实验——数据库基本操作
期末考试复习总结