建模班次规划应用程序:
我提出了描述shift
。
{
"fromHour" : 7,
"fromMinute" : 30,
"toHour" : 9,
"toMinute" : 30,
"week" : 5,
"date" : "2015-01-26",
"user" : {
// ...
},
"_id" : ObjectId("54d0e4a82b9dc26c0c0f36e7")
}
我需要存储的主要信息是: 1.当班次开始时(小时和分钟), 2.换班结束时(小时和分钟)和 它实际发生的日期。
字段fromHour
,fromMinute
,toHour
,toMinute
和date
作为ISO字符串对我来说非常适合存储和查询特定的班次日期。
当我需要从中构建报告时,问题就出现了。说,我希望从07:00到23:00之间的所有班次从“2015-01-01”到“2015-02-01”。
我可以在查询中添加$and
子句,例如
[ { fromHour: { '$gte': 7 } },
{ fromMinute: { '$gte': 0 } },
{ toHour: { '$lt': 23 } },
{ toMinute: { '$lt': 0 } } ]
但是这样做效果不好,因为在toMinute
转换为$lt
时,{{1}}将为假。
我正在努力寻找能够存储易于查询的时间跨度的高效数据结构。
答案 0 :(得分:2)
在两个不同的字段中存储小时和分钟太容易出错,这使您的工作更加困难。由于Mongo没有明显的" Time"数据类型,只有日期,并且班次通常在" easy"开始和结束。有些时候,我建议实现类似的方法,例如将时间转换为应用程序中的实数:
00:00 --> 0
01:00 --> 1
...
08:00 --> 8
08:15 --> 8.25
08:30 --> 8.5
...
16:30 --> 16.5
...
在应用程序中有一些额外的工作,因为您必须在保存或显示时进行转换,但它仍然比在两个不同的字段中具有单个时间值更好。
所以你的数据看起来像这样:
{
"shiftStart" : 7.5,
"shiftEnd" : 9.5,
"week" : 5,
"date" : "2015-01-26",
"user" : {
// ...
},
"_id" : ObjectId("54d0e4a82b9dc26c0c0f36e7")
}
和您的查询:
[ { shiftStart: { '$gte': 7 } },
{ shiftEnd: { '$lt': 23 } } ]
答案 1 :(得分:1)
您可以使用ISODate(...)
格式存储日期类型的数据,然后使用$project
和Date Aggregation Operators查询数据。
对于你的例子:
db.shifts.aggregate([
{ $match: //matches the dates first to filter out before $project step
{ datetimeStart:
{ $gte: ISODate("2015-01-01T07:00:00.000Z"),
$lt: ISODate("2015-02-01T00:00:00.000Z")
},
datetimeEnd:
{ $gte: ISODate("2015-01-01T07:00:00.000Z"),
$lt: ISODate("2015-02-01T00:00:00.000Z")
}
}
},
{ $project: // $project step extracts the hours
{ otherNeededFields: 1, // any other fields you want to see
datetimeStart: 1,
datetimeEnd: 1,
hourStart: { $hour: "$datetimeStart" },
hourEnd: { $hour: "$datetimeEnd" }
}
},
{ $match: // match the shift hours
{ hourStart: { $gte: 7 },
hourEnd: { $lte: 23 }
}
}
])
使用此系统可能可能,但复杂可在上午7:30至晚上10:30之间找到更多类似的内容:
db.shifts.aggregate([
{ $match: //matches the dates first to filter out before $project step
{ datetimeStart:
{ $gte: ISODate("2015-01-01T07:30:00.000Z"),
$lt: ISODate("2015-02-01T00:00:00.000Z")
},
datetimeEnd:
{ $gte: ISODate("2015-01-01T07:30:00.000Z"),
$lt: ISODate("2015-02-01T00:00:00.000Z")
}
}
},
{ $project: // $project step extracts the hours
{ otherNeededFields: 1, // any other fields you want to see
datetimeStart: 1,
datetimeEnd: 1,
hourStart: { $hour: "$datetimeStart" },
minStart: { $minute: "$datetimeStart" },
hourEnd: { $hour: "$datetimeEnd" },
minEnd: { $minute: "$date
}
},
{ $match: // match the shift hours
{ $or:
[
{hourStart: 7, minStart: {$gte: 30}}, // hour is 7, minute >= 30
{hourStart: { $gte: 8 }} // hour is >= 8
],
$or:
[
{hourEnd: 22, minEnd: {$lte: 30}}, // hour is 22, minute <= 30
{hourEnd: { $lte: 21 }} // hour is <= 21
]
}
}
])