检查法语 MongoDB 聚合中两个日期之间的当前日期是否
Check if current date between two dates in french MongoDB aggregation
我的 MongoDB 数据库中有一组餐厅文档,其中的营业时间字段格式如下。
如何使用 MongoDB 聚合检查餐厅现在是否营业?
我的营业时间字段有这样的数据(包括法国日):
{
"Lundi": [
"08:00",
"23:00"
],
"Mardi": [
"08:00",
"23:00"
],
"Mercredi": [
"08:00",
"23:00"
],
"Jeudi": [
"08:00",
"23:00"
],
"Vendredi": [
"08:00",
"23:00"
],
"Samedi": [
"08:00",
"23:00"
],
"Dimanche": [
"08:00",
"23:00"
]
}
查询
- 使用系统变量
"$$NOW"
获取服务器当前时间
- 将每天的开放时间转换为分钟范围(也适用于分钟)
open = 01:00
close = 02:30
限制=[60,150]
- 如果当前时间是
01:30
则 min-now=90
- 然后在
limits
里面过滤day=dayNow
min-now
(例如,在我们的示例中 90
处于极限 [60,150]
)
- 如果至少有 1 个通过,则过滤器存储打开,否则关闭
查询
aggregate(
[{"$project":{"_id":0}},
{"$project":
{"open":
{"$filter":
{"input":
{"$map":
{"input":{"$objectToArray":"$$ROOT"},
"in":["$$this.k", "$$this.v"]}},
"cond":
{"$let":
{"vars":
{"info":
{"day":{"$arrayElemAt":["$$r", 0]},
"limits":
[{"$add":
[{"$multiply":
[{"$toInt":
{"$arrayElemAt":
[{"$split":
[{"$arrayElemAt":[{"$arrayElemAt":["$$r", 1]}, 0]},
":"]},
0]}},
60]},
{"$toInt":
{"$arrayElemAt":
[{"$split":
[{"$arrayElemAt":[{"$arrayElemAt":["$$r", 1]}, 0]},
":"]},
1]}}]},
{"$add":
[{"$multiply":
[{"$toInt":
{"$arrayElemAt":
[{"$split":
[{"$arrayElemAt":[{"$arrayElemAt":["$$r", 1]}, 1]},
":"]},
0]}},
60]},
{"$toInt":
{"$arrayElemAt":
[{"$split":
[{"$arrayElemAt":[{"$arrayElemAt":["$$r", 1]}, 1]},
":"]},
1]}}]}],
"day-now":
{"$arrayElemAt":
[["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi",
"Samedi", "Dimanche"],
{"$subtract":[{"$dayOfWeek":"$$NOW"}, 1]}]},
"min-now":
{"$add":
[{"$multiply":[{"$hour":"$$NOW"}, 60]},
{"$minute":"$$NOW"}]}}},
"in":
{"$and":
[{"$eq":["$$info.day", "$$info.day-now"]},
{"$gte":
["$$info.min-now", {"$arrayElemAt":["$$info.limits", 0]}]},
{"$lte":
["$$info.min-now",
{"$arrayElemAt":["$$info.limits", 1]}]}]}}},
"as":"r"}}}},
{"$project":{"open":{"$ne":["$open", []]}, "date-now":"$$NOW"}}])
真是丑陋的数据模型。您必须将法国日期名称翻译成数字,将时间值翻译成 Date
对象。然后您可以按日期和时间筛选:
db.collection.aggregate([
{ $unset: "_id" },
{
$project: {
opening_times: {
$map: {
input: { $objectToArray: "$$ROOT" },
in: {
day: {
$switch: {
branches: [
{ case: { $eq: ["Lundi", "$$this.k"] }, then: 1 },
{ case: { $eq: ["Mardi", "$$this.k"] }, then: 2 },
{ case: { $eq: ["Mercredi", "$$this.k"] }, then: 3 },
{ case: { $eq: ["Jeudi", "$$this.k"] }, then: 4 },
{ case: { $eq: ["Vendredi", "$$this.k"] }, then: 5 },
{ case: { $eq: ["Samedi", "$$this.k"] }, then: 6 },
{ case: { $eq: ["Dimanche", "$$this.k"] }, then: 7 }
]
}
},
open: {
$dateFromParts: {
year: { $year: "$$NOW" }, month: { $month: "$$NOW" }, day: { $dayOfMonth: "$$NOW" },
hour: { $toInt: { $first: { $split: [{ $first: "$$this.v" }, ":"] } } },
minute: { $toInt: { $last: { $split: [{ $first: "$$this.v" }, ":"] } } },
timezone: "Europe/Paris"
}
},
close: {
$dateFromParts: {
year: { $year: "$$NOW" }, month: { $month: "$$NOW" }, day: { $dayOfMonth: "$$NOW" },
hour: { $toInt: { $first: { $split: [{ $last: "$$this.v" }, ":"] } } },
minute: { $toInt: { $last: { $split: [{ $last: "$$this.v" }, ":"] } } },
timezone: "Europe/Paris"
}
}
}
}
}
}
},
{
$project: {
open_today: {
$first: {
$filter: {
input: "$opening_times",
cond: { $eq: ["$$this.day", { $isoDayOfWeek: "$$NOW" }] }
}
}
}
}
},
{
$project: {
restaurant: {
$cond: {
if: {
$and: [
{ $gte: ["$$NOW", "$open_today.open"] },
{ $lt: ["$$NOW", "$open_today.close"] },
]
},
then: "open",
else: "close"
}
}
}
}
])
我的 MongoDB 数据库中有一组餐厅文档,其中的营业时间字段格式如下。
如何使用 MongoDB 聚合检查餐厅现在是否营业?
我的营业时间字段有这样的数据(包括法国日):
{
"Lundi": [
"08:00",
"23:00"
],
"Mardi": [
"08:00",
"23:00"
],
"Mercredi": [
"08:00",
"23:00"
],
"Jeudi": [
"08:00",
"23:00"
],
"Vendredi": [
"08:00",
"23:00"
],
"Samedi": [
"08:00",
"23:00"
],
"Dimanche": [
"08:00",
"23:00"
]
}
查询
- 使用系统变量
"$$NOW"
获取服务器当前时间 - 将每天的开放时间转换为分钟范围(也适用于分钟)
open = 01:00
close = 02:30
限制=[60,150]
- 如果当前时间是
01:30
则min-now=90
- 然后在
limits
里面过滤day=dayNow
min-now
(例如,在我们的示例中90
处于极限[60,150]
) - 如果至少有 1 个通过,则过滤器存储打开,否则关闭
查询
aggregate(
[{"$project":{"_id":0}},
{"$project":
{"open":
{"$filter":
{"input":
{"$map":
{"input":{"$objectToArray":"$$ROOT"},
"in":["$$this.k", "$$this.v"]}},
"cond":
{"$let":
{"vars":
{"info":
{"day":{"$arrayElemAt":["$$r", 0]},
"limits":
[{"$add":
[{"$multiply":
[{"$toInt":
{"$arrayElemAt":
[{"$split":
[{"$arrayElemAt":[{"$arrayElemAt":["$$r", 1]}, 0]},
":"]},
0]}},
60]},
{"$toInt":
{"$arrayElemAt":
[{"$split":
[{"$arrayElemAt":[{"$arrayElemAt":["$$r", 1]}, 0]},
":"]},
1]}}]},
{"$add":
[{"$multiply":
[{"$toInt":
{"$arrayElemAt":
[{"$split":
[{"$arrayElemAt":[{"$arrayElemAt":["$$r", 1]}, 1]},
":"]},
0]}},
60]},
{"$toInt":
{"$arrayElemAt":
[{"$split":
[{"$arrayElemAt":[{"$arrayElemAt":["$$r", 1]}, 1]},
":"]},
1]}}]}],
"day-now":
{"$arrayElemAt":
[["Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi",
"Samedi", "Dimanche"],
{"$subtract":[{"$dayOfWeek":"$$NOW"}, 1]}]},
"min-now":
{"$add":
[{"$multiply":[{"$hour":"$$NOW"}, 60]},
{"$minute":"$$NOW"}]}}},
"in":
{"$and":
[{"$eq":["$$info.day", "$$info.day-now"]},
{"$gte":
["$$info.min-now", {"$arrayElemAt":["$$info.limits", 0]}]},
{"$lte":
["$$info.min-now",
{"$arrayElemAt":["$$info.limits", 1]}]}]}}},
"as":"r"}}}},
{"$project":{"open":{"$ne":["$open", []]}, "date-now":"$$NOW"}}])
真是丑陋的数据模型。您必须将法国日期名称翻译成数字,将时间值翻译成 Date
对象。然后您可以按日期和时间筛选:
db.collection.aggregate([
{ $unset: "_id" },
{
$project: {
opening_times: {
$map: {
input: { $objectToArray: "$$ROOT" },
in: {
day: {
$switch: {
branches: [
{ case: { $eq: ["Lundi", "$$this.k"] }, then: 1 },
{ case: { $eq: ["Mardi", "$$this.k"] }, then: 2 },
{ case: { $eq: ["Mercredi", "$$this.k"] }, then: 3 },
{ case: { $eq: ["Jeudi", "$$this.k"] }, then: 4 },
{ case: { $eq: ["Vendredi", "$$this.k"] }, then: 5 },
{ case: { $eq: ["Samedi", "$$this.k"] }, then: 6 },
{ case: { $eq: ["Dimanche", "$$this.k"] }, then: 7 }
]
}
},
open: {
$dateFromParts: {
year: { $year: "$$NOW" }, month: { $month: "$$NOW" }, day: { $dayOfMonth: "$$NOW" },
hour: { $toInt: { $first: { $split: [{ $first: "$$this.v" }, ":"] } } },
minute: { $toInt: { $last: { $split: [{ $first: "$$this.v" }, ":"] } } },
timezone: "Europe/Paris"
}
},
close: {
$dateFromParts: {
year: { $year: "$$NOW" }, month: { $month: "$$NOW" }, day: { $dayOfMonth: "$$NOW" },
hour: { $toInt: { $first: { $split: [{ $last: "$$this.v" }, ":"] } } },
minute: { $toInt: { $last: { $split: [{ $last: "$$this.v" }, ":"] } } },
timezone: "Europe/Paris"
}
}
}
}
}
}
},
{
$project: {
open_today: {
$first: {
$filter: {
input: "$opening_times",
cond: { $eq: ["$$this.day", { $isoDayOfWeek: "$$NOW" }] }
}
}
}
}
},
{
$project: {
restaurant: {
$cond: {
if: {
$and: [
{ $gte: ["$$NOW", "$open_today.open"] },
{ $lt: ["$$NOW", "$open_today.close"] },
]
},
then: "open",
else: "close"
}
}
}
}
])