好的,我正在使用MongoDB作为数据库的Web应用程序。与Mongodb一起工作非常简单,但现在我遇到了让我遇到麻烦的限制。
在一个收藏中我保存了活动。在其他字段中,这些事件具有开始和结束,在Mongodb中保存为Dates
。
events {
start: "Date1",
end: "Date2",
...
}
在此集合中插入新文档时,我需要一个禁止插入文档的约束,该文档的开始日期与创建的事件重叠。简而言之,我不希望任何事件共享相同的时间跨度。
总而言之,这在MongoDB中是不可能做到的,相反,我发现自己在数据库的局限性下设计了数据结构。折衷方案是以离散的15分钟步骤分割时间范围,并将它们放入一个给定唯一索引的数组中。
我认为所有的数据库都有它的起伏,但我想听听谁知道postgressql是否会出现问题?
答案 0 :(得分:1)
你可以通过在数组上使用唯一索引(通过将时间段表示为时间片数组)的一个(有点尴尬)技巧来强制执行此操作,我认为这是你在问题中提到的。您还可以使用findAndModify和$setOnInsert在客户端轻松实施此约束:
db.events.findAndModify({
"query" : { "start" : {"$lte" : end_time }, "end" : { "$gte" : start_time } },
"update" : { // setOnInsert operators }
"upsert" : true
})
如果您在文档上有某种唯一ID,则可以通过检查findAndModify返回的唯一ID与您尝试插入的新doc的ID来判断是否存在重叠。如果不需要check + insert的原子性,你也可以进行查找,然后有条件地插入。
要回复您的第一条评论,findAndModify方法不适用于原子更改。您可以通过处理两个文档(旧文档和新文档)或更改旧文档中的时间来更改时间范围。第一种方法不能是原子的,因为它影响多个文档,并且通常只在MongoDB中的每个文档级别保证原子性。第二种方法不能轻易地尊重非重叠约束,因为更新不能相对于另一个文档,并且除了重叠值之外没有办法使用唯一索引进行重叠(这个尴尬的技巧我之前预订了)。我永远不会把它描述为优雅,但我认为时间片的数组实际上非常适用于涉及预订等事情的许多用例,因为所有时间段都是最小时间段的倍数,通常为15或30分钟。管理应用程序代码中的重叠也是完全可行的(以及我将如何进行)。
要回复第二个问题,我们会在public JIRA project中跟踪要求,正在处理和计划发布的各种功能,因此您应该在那里挖掘一下,看看您是否能找到您想要的内容。我认为没有任何一种功能可以实现某种索引来防止重叠。这不是常见的需求,可以在应用程序代码中处理。您可以随时提交功能请求并查看它是否与工程师有关,但我认为他们会说它的应用程序非常适合使用MongoDB中已有的工具在应用程序端进行最佳处理。