你如何在mongoDB中的文档中存储开放时间,比如使用Mongoid可以轻松查询?我读过this帖子,但我不确定如何根据我的需要实现它。
我需要能够每天添加多个开放和关闭时间,因为图书馆应该能够在一天中关闭几个小时然后重新打开。
我需要能够在这些开放时间添加例外。例如;在特定日期关闭星期一。
请分享一些关于如何以最灵活的方式做到这一点的最佳实践和经验。
答案 0 :(得分:5)
谢谢Yeggeps的要求清单。
这是根据您的要求修改的答案。当然,模式没有圣杯,但我希望在修订之前激发我的答案(保持平面结构易于查询和维护),并根据您的需求列表提供一些示例数据+查询。我重申,我并不是说这是最好的解决方案,但它是 解决方案,它易于查询且易于维护(imho)。
代码有点快速和肮脏,道歉。数据:
[
# library "lib1" open on wednesdays from 8:00 until 17:00
{"lib_id" => "lib1", "type" => "hours", "opening" => 800, "closing" => 1700, "day_of_week" => 3},
# library "lib1" open on wednesdays from 19:00 until 22:15
{"lib_id" => "lib1", "type" => "hours", "opening" => 1900, "closing" => 2215, "day_of_week" => 3},
{"lib_id" => "lib1", "type" => "hours", "opening" => 800, "closing" => 1700, "day_of_week" => 4},
{"lib_id" => "lib2", "type" => "hours", "opening" => 1100, "closing" => 1700, "day_of_week" => 3},
{"lib_id" => "lib2", "type" => "hours", "opening" => 1400, "closing" => 1700, "day_of_week" => 4},
{"lib_id" => "lib2", "type" => "hours", "opening" => 1900, "closing" => 2100, "day_of_week" => 4},
# library lib1 closed on wednesday december 7th 2011
{"lib_id" => "lib1", "type" => "closed_on", "reason" => "Rearranging the shelves", "closed_date" => Time.utc(2011, 12, 8)},
{"lib_id" => "lib2", "type" => "closed_on", "reason" => "We are closed for the holidays", "closed_date" => Time.utc(2011, 12, 7)}
].each do |schedule|
coll.save(schedule)
end
分别显示营业时间和特殊日期:
# List all the library id's distinctly
coll.distinct("lib_id").each do |lib_id|
puts "\nLibrary #{lib_id} opening hours:\n--- "
# I need to be able to show the opening hours in correlation with the Library
# Find all the opening hour information for current library
coll.find({"lib_id" => lib_id, "type" => "hours"}).each do |schedule|
puts " #{Date::DAYNAMES[schedule["day_of_week"]]}s: #{schedule["opening"]} - #{schedule["closing"]}" if schedule["type"] == "hours"
end
# I need to show an indication if it's open or closed in correlation with the Library.
puts "This library will be closed on: "
# Find all the exceptions for current lib_id -- introduce a time-period restriction using Date.utc (...)
coll.find({"lib_id" => lib_id, "type" => "closed_on"}).each do |closed|
puts " #{closed["closed_date"].strftime("%a %B%e, %Y")}: #{closed["reason"]}"
end
end
今天哪些图书馆开放?
# I need to be able to query on what's open right now or some time in the future with minute granularity
# here I'll also need to be able to exclude the Librarys that has added exceptions for the given time/day
puts "---"
qtime = (Time.now.hour * 100) + Time.now.min # minute granularity
qwday = Time.now.wday # this example only shows today
qclosed = Time.utc(Time.now.year, Time.now.mon, Time.now.mday)
# Query for all library ids which have opening times for this weekday, at this hour (+minutes)
coll.find({"opening" => {"$lte" => qtime}, "closing" => {"$gte" => qtime}, "day_of_week" => qwday}, {:fields => "lib_id"}).each do |lib|
# Check whether current library has an exception for this specific day
closed = coll.find_one({"lib_id" => lib["lib_id"], "closed_date" => qclosed})
if closed
# If an exception record was encountered, print the reason
puts "Library #{lib["lib_id"]} is normally open right now, but is now closed: '#{closed["reason"]}'"
else
# Else: the library is open
puts "Library #{lib["lib_id"]} is open right now! (#{Time.now.strftime("%a %B%e %Y, %H:%M")})"
end
end
按如下方式生成输出:
Library lib1 opening hours:
---
Wednesdays: 800 - 1700
Wednesdays: 1900 - 2215
Thursdays: 800 - 1700
This library will be closed on:
Thu December 8, 2011: Rearranging the shelves
Library lib2 opening hours:
---
Wednesdays: 1100 - 1700
Thursdays: 1400 - 1700
Thursdays: 1900 - 2100
This library will be closed on:
Wed December 7, 2011: We are closed for the holidays
---
Library lib1 is open right now! (Wed December 7 2011, 13:12)
Library lib2 is normally open right now, but is now closed: 'We are closed for the holidays'
不可否认,我提出的解决方案的缺点是它无法捕获一个查询中的所有要求。
答案 1 :(得分:2)
如果不知道您想要运行的确切查询,很难提供一个好的解决方案。例如,如果你问“现在哪些企业是开放的(2011年5月5日下午5点32分)?”你想要一个不同的模式,而不是你问“下一个商业XYZ何时开放?”
在第一种情况下,您希望能够在当前小时,分钟和日期有效地构建范围查询 - 以及在例外列表上进行否定查询。或者,您可以在客户端代码中处理异常。
最后,所需的粒度级别是多少?可能的最小例外是什么?分钟?小时?天?
我将上述内容发布为评论,但我刚创建了一个用户帐户。有了附加信息,我会更新此信息以提供实际答案。