检查法语 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:30min-now=90
  • 然后在limits里面过滤day=dayNowmin-now (例如,在我们的示例中 90 处于极限 [60,150]
  • 如果至少有 1 个通过,则过滤器存储打开,否则关闭

Test code here

查询

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"
            }
         }
      }
   }
])

Mongo playground