大家。 我想弄清楚Google Datastore是否是我个案中的最佳选择..
我需要按照以下时间表存储员工:
id
name
schedule
时间表如下:
Mon 10am-10pm (simple)
Tue 10am-5pm, 5.30pm-8pm (multiple, not even hours)
..
Sun 6pm-4am (start/end are in different days)
如果员工现在正在工作,其中一个API会返回
我尝试使用数据存储但GQL查询似乎非常有限,例如您无法在一个查询中比较两个不同的属性(例如
.. WHERE current_time>start_time AND current_time<close_time
您不能使用不等于运算符(小于,等于) 同一查询中的不同属性名称。
这意味着我需要将大量实体加载到我的后台并解析它们,浪费时间和资源......而不是直接从数据库中获取结果
提前感谢!
答案 0 :(得分:4)
根据您的示例,我将假设工作班次以30分钟为增量。如果不是这种情况,您可以轻松调整以下内容,但您可能需要考虑一些优化。
以下解决方案将为员工提供持续的时间查看,无论他们工作多少班次。它还可以无缝地处理从一天到下一天的轮班。
我将使用以下稻草人实体
实体种类:员工
- id:自动识别
- 名称:字符串
- schedule:重复整数,索引
24小时为您提供48个30分钟的周期,所以让我们将整数映射到时间段:
此整数很容易从您当前的时间推导出来。使用java.util.Calendar和java.util.Date:
Date date = new Date(); // Initializes to now.
Calendar calendar = GregorianCalendar.getInstance();
calendar.setTime(date);
int hour = calendar.get(Calendar.HOUR_OF_DAY); // Hour in 24h format
int minute = calendar.get(Calendar.MINUTE); // Minute of the hour
int period = hour*60 + minute/30*30; // Integer division rounds down to nearest 30
我在compilejava.net上测试了这个,测试代码在这里:https://gist.github.com/55a98bbdb9b5eb3eeaee5f8984f11687
现在我们有30分钟的时段,我们应该在星期几合并(星期日= 0,星期六= 6)。由于最长30分钟的周期值是1440,因此可以方便地将一周中的几天乘以10000,这样我们就可以将它们加在一起而不会发生冲突:
int day = calendar.get(Calendar.DAY_OF_WEEK);
int day_period = day*10000 + period;
此处扩展了测试代码:https://gist.github.com/217221e03b3eb143b4be45bf3f641d25
现在,不要将您的日程安排存储为每天的开始和停止时间,而是使用上面相同的想法来存储员工安排的每30分钟的时间段。在你的例子中,你有:
Mon 10am-10pm (simple)
Tue 10am-5pm, 5.30pm-8pm (multiple, not even hours)
..
Sun 6pm-4am (start/end are in different days)
在计划字段(重复整数)中,这看起来像:
10600,10630,10660,10690,10720,10750,10780,10810,10840,10870,10900,10930,10960,10990,11020,
11050,11080,11110,11140,11170,11200,11230,11260,11290,20600,20630,20660,20690,20720,20750,
20780,20810,20840,20870,20900,20930,20960,20990,21050,21080,21110,21140,21170,1080,1110,
1140,1170,1200,1230,1260,1290,1320,1350,1380,1410,0,30,60,90,120,150,180,210
现在查询非常简单,只是平等。这将为每个现在正在工作的员工实体提供O(1)性能,或者更一般地为O(n),其中n
是现在正在工作的员工数(而不是总员工数)。
... WHERE schedule=day_period
答案 1 :(得分:1)
您可以存储开始时间和结束时间的长表示。 1小时= 3600000毫秒。因此,如果00-00是参考点,则02-00将由2 x 3600000表示。
另一种选择是存储java.util.Date
(一个用于开始时间,一个用于结束时间)