Python 根据门店营业时间有效确定企业是否营业

Python 根据门店营业时间有效确定企业是否营业,python,mysql,performance,solr,Python,Mysql,Performance,Solr,给定一个时间(例如,目前周二下午4:24),我希望能够从一组业务中选择当前开放的所有业务 我有一周中每一天的营业时间和营业时间 让我们假设一家公司只能在每小时的00、15、30、45分钟开盘/收盘 我每周的日程安排都是一样的 我最感兴趣的是能够快速查找在特定时间开放的一组业务,而不是数据的空间要求 请注意,我的一些店前一天晚上11点开门,第二天凌晨1点关门 假期没关系,我会单独处理的 存储这些打开/关闭时间的最有效方法是什么,这样,通过一个时间/一周中的一天元组,我可以快速确定哪些业务是打开

给定一个时间(例如,目前周二下午4:24),我希望能够从一组业务中选择当前开放的所有业务

  • 我有一周中每一天的营业时间和营业时间
  • 让我们假设一家公司只能在每小时的00、15、30、45分钟开盘/收盘
  • 我每周的日程安排都是一样的
  • 我最感兴趣的是能够快速查找在特定时间开放的一组业务,而不是数据的空间要求
  • 请注意,我的一些店前一天晚上11点开门,第二天凌晨1点关门
  • 假期没关系,我会单独处理的
存储这些打开/关闭时间的最有效方法是什么,这样,通过一个时间/一周中的一天元组,我可以快速确定哪些业务是打开的


我正在使用Python、SOLR和mysql。我希望能够在SOLR中进行查询。但坦率地说,我愿意接受任何建议和替代方案。

很抱歉,我没有一个简单的答案,但我可以告诉你,作为90年代末一家公司开发团队的经理,我们的任务就是解决这个问题,这很难

这不是每周的工作时间很难,这可以用一个相对较小的位掩码(168位=每周每小时1个)来完成,诀窍是每周二关闭一次的业务


从一个位掩码开始,然后转到一个异常字段是我见过的最好的解决方案。

另一个受访者提到的位图字段效率极高,但如果你想处理半小时或四分之一小时的时间,它会变得很混乱,因为每次遇到需要匹配的新分辨率时,必须以算术方式增加位数和字段的设计

我会尝试将值存储为列表中的日期时间:

openclosings = [ open1, close1, open2, close2, ... ]
然后,我将在其内置的“bisect”模块中使用Python的“bisect_right()”函数,以快速的O(logn)时间查找您的查询时间“适合”列表的位置。然后,查看返回的索引。如果是偶数(0、2、4…),则时间介于一个“关闭”时间和下一个“打开”时间之间,因此此时商店关闭。相反,如果平分指数为奇数(1、3、5…),则开店时间与关门时间之间的时间已到达,且店铺已开张


没有位图那么快,但你不必担心分辨率,我想不出另一个O(logn)解决方案那么优雅。

如果你愿意一次只看一周,你可以规范化所有的开始/结束时间,以设置从一周开始的分钟数,比如周日0小时。对于每个存储,您可以创建许多元组,其形式为[startTime、endTime、storeId]。(对于跨越周日午夜的几个小时,您必须创建两个元组,一个在周末,一个在周初)。这组元组将在startTime和endTime上建立索引(比如,使用一个预处理的树)。元组不应该那么大:一周只有约10万分钟,可以容纳2个字节。这种结构在具有适当索引的MySQL表中是优雅的,并且随着信息的更改,对记录的不断插入和删除非常有弹性。您的查询将只是“selectstoreid where startTime=time”,其中时间是自周日午夜以来的标准化分钟数


如果信息不经常更改,并且您希望查找速度非常快,那么您可以提前解决所有可能的查询并缓存结果。例如,一周中只有672节四分之一小时。有了一个企业列表,每个企业都有一个像Brandon Rhodes的解决方案那样的开盘和收盘时间列表,你只需在一周内每15分钟迭代一次,找出谁在开盘,然后将答案存储在查找表或内存列表中。

你说你在使用SOLR,不在乎存储,并希望快速查找。然后,不用存储打开/关闭元组,而是按照您需要的粒度级别(15分钟)为每个打开的时间块索引一个条目。对于编码本身,您可以使用累积小时数:分钟

例如,周一下午4-5点营业的商店将为[40:00、40:15、40:30、40:45]添加索引值。周一下午4:24的查询将标准化为40:15,因此与该存储文档匹配


乍一看,这似乎效率低下,但对于索引速度和空间来说,这是一个相对较小的持续损失。并使搜索尽可能快。

如果你能很好地控制数据,我看到一个简单的解决方案,类似于@Sebastian的。遵循创建元组的建议,除了创建[time=startTime,storeId]和[time=endTime,storeId]形式的元组,然后在列表中对它们进行排序。要确定某个存储是否已打开,只需执行如下查询:

select storeId
from table
where time <= '@1'
group by storeId
having count(storeId) % 2 == 1
选择storeId
从桌子上

where time您是否查看了有多少独特的打开/关闭时间组合?如果没有那么多,就制作一个独特组合的参考表,并针对每个业务存储相应条目的索引。然后,您只需搜索参考表,然后找到具有这些索引的业务。

在Solr索引中,不是将每个业务作为一个小时的文档进行索引,而是在一周内为每个业务的每个“零售会话”编制索引

例如,如果Joe's coffee周一至周六上午6点至晚上9点开放,周日关闭,您将为六个不同的文档编制索引,每个文档都有两个索引字段“open”和“close”。如果单位为15分钟间隔,则值的范围为0到7*24*4。假设每个业务都有一个唯一的ID,请将其存储在每个文档中,以便将会话映射到业务