【问题标题】:Can we compare only time in mongodb?我们可以只比较MongoDB中的时间吗?
【发布时间】:2016-05-02 07:51:13
【问题描述】:

我已经以日期时间格式存储了happyHours 酒店。现在我想获取所有happyHours 大于当前时间的酒店。

据我所知,我知道有日期比较来获取结果,但这会比较整个日期时间对象。

有没有办法只比较时间?

db 中的欢乐时光日期对象示例:

"happyHours" : {
    "mon" : [ 
        {
            "startTime" : ISODate("2016-04-11T06:30:59.000Z"),
            "endTime" : ISODate("2016-04-11T14:30:59.000Z")
        }
    ],
    "tue" : [ 
        {
            "startTime" : ISODate("2016-04-11T06:30:59.000Z"),
            "endTime" : ISODate("2016-04-11T14:30:59.000Z")
        }
    ],
    "wed" : [ 
        {
            "startTime" : ISODate("2016-04-11T06:30:59.000Z"),
            "endTime" : ISODate("2016-04-11T14:30:59.000Z")
        }
    ],
    "thu" : [ 
        {
            "startTime" : ISODate("2016-04-11T06:30:59.000Z"),
            "endTime" : ISODate("2016-04-11T14:30:59.000Z")
        }
    ],
    "fri" : [ 
        {
            "startTime" : ISODate("2016-04-11T06:30:59.000Z"),
            "endTime" : ISODate("2016-04-11T14:30:59.000Z")
        }
    ],
    "sat" : [ 
        {
            "startTime" : ISODate("2016-04-11T06:30:59.000Z"),
            "endTime" : ISODate("2016-04-11T14:30:59.000Z")
        }
    ],
    "sun" : [ 
        {
            "startTime" : ISODate("2016-04-11T06:30:59.000Z"),
            "endTime" : ISODate("2016-04-11T14:30:59.000Z")
        }
    ]
}

【问题讨论】:

  • 如何在日期时间保持酒店的欢乐时光?如果我是对的,欢乐时光应该与日期无关..
  • 是的,我同意你的建议。但这是现有数据库的结构。所以我试图通过比较时间来获取它们。
  • 还有过去的日期吗?
  • 是的,我已经用示例更新了问题。

标签: mongodb time datetime-conversion


【解决方案1】:

首先,当前模式不利于查询;在这种情况下,数组实际上是不必要的,如果您要将工作日作为键,那么更好的方法是丢失数组并仅引用元素:

"happyHours": {
    "mon": {
        "startTime" : ISODate("2016-04-11T06:30:59.000Z"),
        "endTime" : ISODate("2016-04-11T14:30:59.000Z")
    },
    ...
    "sun": {
        "startTime" : ISODate("2016-04-11T06:30:59.000Z"),
        "endTime" : ISODate("2016-04-11T14:30:59.000Z")
    }    
}

但是,一个更好的设计使查询更容易招手。您可以将happyHours 字段转换为一个数组,该数组包含一个文档,该文档分别描述了工作日、开始时间、开始分钟、结束小时和分钟,如下所示:

"happyHours": [
    {
        "weekDay": "mon",
        "startHour": 6,
        "startMinutes": 30,
        "endHour": 14
        "endMinutes": 30
    }
    ...
]

那么查询如下:

var now = new Date(),
    days = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sun'],
    weekDay = days[now.getDay()],
    hour = now.getHours(),
    minutes = now.getMinutes();

db.hotels.find({
    "happyHours.weekDay": weekDay,
    "happyHours.startHour": { "$lte": hour },
    "happyHours.startMinutes": { "$lte": minutes },
    "happyHours.endHour": { "$gte": hour },
    "happyHours.endMinutes": { "$gte": minutes }
})

现在,如果您没有能力修改架构以符合上述建议,那么聚合框架提供了一种解决方法。考虑以下聚合管道,它在 $project 步骤中使用 date aggregation operators 并在随后的 $match 管道中查询:

 var now = new Date(),
    days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sun'],
    weekDay = days[now.getDay()],
    hour = now.getHours(),
    minutes = now.getMinutes();
    project = {
    "$project": {
        "otherfields": 1,
        "happyHours": 1,
        "happyHoursMonStartHour": { "$hour": "$happyHours.mon.startTime" },
        "happyHoursMonStartMinutes": { "$minute": "$happyHours.mon.startTime" },
        "happyHoursMonEndHour": { "$hour": "$happyHours.mon.endTime" },
        "happyHoursMonEndMinutes": { "$minute": "$happyHours.mon.endTime" },
        "happyHoursTueStartHour": { "$hour": "$happyHours.tue.startTime" },
        "happyHoursTueStartMinutes": { "$minute": "$happyHours.tue.startTime" },
        "happyHoursTueEndHour": { "$hour": "$happyHours.tue.endTime" },
        "happyHoursTueEndMinutes": { "$minute": "$happyHours.tue.endTime" },
        "happyHoursWedStartHour": { "$hour": "$happyHours.wed.startTime" },
        "happyHoursWedStartMinutes": { "$minute": "$happyHours.wed.startTime" },
        "happyHoursWedEndHour": { "$hour": "$happyHours.wed.endTime" },
        "happyHoursWedEndMinutes": { "$minute": "$happyHours.wed.endTime" },
        "happyHoursThuStartHour": { "$hour": "$happyHours.thu.startTime" },
        "happyHoursThuStartMinutes": { "$minute": "$happyHours.thur.startTime" },
        "happyHoursThuEndHour": { "$hour": "$happyHours.thu.endTime" },
        "happyHoursThuEndMinutes": { "$minute": "$happyHours.thu.endTime" },
        "happyHoursFriStartHour": { "$hour": "$happyHours.fri.startTime" },
        "happyHoursFriStartMinutes": { "$minute": "$happyHours.fri.startTime" },
        "happyHoursFriEndHour": { "$hour": "$happyHours.fri.endTime" },
        "happyHoursFriEndMinutes": { "$minute": "$happyHours.fri.endTime" },
        "happyHoursSatStartHour": { "$hour": "$happyHours.sat.startTime" },
        "happyHoursSatStartMinutes": { "$minute": "$happyHours.sat.startTime" },
        "happyHoursSatEndHour": { "$hour": "$happyHours.sat.endTime" },
        "happyHoursSatEndMinutes": { "$minute": "$happyHours.sat.endTime" },
        "happyHoursSunStartHour": { "$hour": "$happyHours.sun.startTime" },
        "happyHoursSunStartMinutes": { "$minute": "$happyHours.sun.startTime" },
        "happyHoursSunEndHour": { "$hour": "$happyHours.sun.endTime" },
        "happyHoursSunEndMinutes": { "$minute": "$happyHours.sun.endTime" },
    }
    },
    match = { "$match": {} },    
    pipeline = [
    { "$unwind": "$happyHours.mon" },
    { "$unwind": "$happyHours.tue" },
    { "$unwind": "$happyHours.wed" },
    { "$unwind": "$happyHours.thur" },
    { "$unwind": "$happyHours.fri" },
    { "$unwind": "$happyHours.sat" },
    { "$unwind": "$happyHours.sun" }    
    ];

match["$match"]["happyHours"+ weekDay +"StartHour"] = { "$lte": hour };
match["$match"]["happyHours"+ weekDay +"StartMinutes"] = { "$lte": minutes };
match["$match"]["happyHours"+ weekDay +"EndHour"] = { "$gte": minutes };
match["$match"]["happyHours"+ weekDay +"EndMinutes"] = { "$gte": minutes };
pipeline.push(project);
pipeline.push(match);

db.hotels.aggregate(pipeline);

在使用printjson(pipeline) 运行管道之前打印管道会显示:

[
    {
        "$unwind" : "$happyHours.mon"
    },
    {
        "$unwind" : "$happyHours.tue"
    },
    {
        "$unwind" : "$happyHours.wed"
    },
    {
        "$unwind" : "$happyHours.thur"
    },
    {
        "$unwind" : "$happyHours.fri"
    },
    {
        "$unwind" : "$happyHours.sat"
    },
    {
        "$unwind" : "$happyHours.sun"
    },
    {
        "$project" : {
            "otherfields" : 1,
            "happyHours" : 1,
            "happyHoursMonStartHour" : {
                "$hour" : "$happyHours.mon.startTime"
            },
            "happyHoursMonStartMinutes" : {
                "$minute" : "$happyHours.mon.startTime"
            },
            "happyHoursMonEndHour" : {
                "$hour" : "$happyHours.mon.endTime"
            },
            "happyHoursMonEndMinutes" : {
                "$minute" : "$happyHours.mon.endTime"
            },
            "happyHoursTueStartHour" : {
                "$hour" : "$happyHours.tue.startTime"
            },
            "happyHoursTueStartMinutes" : {
                "$minute" : "$happyHours.tue.startTime"
            },
            "happyHoursTueEndHour" : {
                "$hour" : "$happyHours.tue.endTime"
            },
            "happyHoursTueEndMinutes" : {
                "$minute" : "$happyHours.tue.endTime"
            },
            "happyHoursWedStartHour" : {
                "$hour" : "$happyHours.wed.startTime"
            },
            "happyHoursWedStartMinutes" : {
                "$minute" : "$happyHours.wed.startTime"
            },
            "happyHoursWedEndHour" : {
                "$hour" : "$happyHours.wed.endTime"
            },
            "happyHoursWedEndMinutes" : {
                "$minute" : "$happyHours.wed.endTime"
            },
            "happyHoursThuStartHour" : {
                "$hour" : "$happyHours.thu.startTime"
            },
            "happyHoursThuStartMinutes" : {
                "$minute" : "$happyHours.thur.startTime"
            },
            "happyHoursThuEndHour" : {
                "$hour" : "$happyHours.thu.endTime"
            },
            "happyHoursThuEndMinutes" : {
                "$minute" : "$happyHours.thu.endTime"
            },
            "happyHoursFriStartHour" : {
                "$hour" : "$happyHours.fri.startTime"
            },
            "happyHoursFriStartMinutes" : {
                "$minute" : "$happyHours.fri.startTime"
            },
            "happyHoursFriEndHour" : {
                "$hour" : "$happyHours.fri.endTime"
            },
            "happyHoursFriEndMinutes" : {
                "$minute" : "$happyHours.fri.endTime"
            },
            "happyHoursSatStartHour" : {
                "$hour" : "$happyHours.sat.startTime"
            },
            "happyHoursSatStartMinutes" : {
                "$minute" : "$happyHours.sat.startTime"
            },
            "happyHoursSatEndHour" : {
                "$hour" : "$happyHours.sat.endTime"
            },
            "happyHoursSatEndMinutes" : {
                "$minute" : "$happyHours.sat.endTime"
            },
            "happyHoursSunStartHour" : {
                "$hour" : "$happyHours.sun.startTime"
            },
            "happyHoursSunStartMinutes" : {
                "$minute" : "$happyHours.sun.startTime"
            },
            "happyHoursSunEndHour" : {
                "$hour" : "$happyHours.sun.endTime"
            },
            "happyHoursSunEndMinutes" : {
                "$minute" : "$happyHours.sun.endTime"
            }
        }
    },
    {
        "$match" : {
            "happyHoursThuStartHour" : {
                "$lte" : 9
            },
            "happyHoursThuStartMinutes" : {
                "$lte" : 34
            },
            "happyHoursThuEndHour" : {
                "$gte" : 34
            },
            "happyHoursThuEndMinutes" : {
                "$gte" : 34
            }
        }
    }
]

【讨论】:

  • 添加数组的原因是酒店可以在同一天的多个时段有happyhours。例如 10 到 11,然后在同一天 20 到 23 就这样。
  • 嗨@zulekha 答案中有什么不清楚的地方吗?
  • 感谢您的宝贵时间。但这对我不起作用,正如我之前解释的那样,我每天可能有很多happyHour时段。
  • 不用担心 :) 如果您无法修改架构,我认为您一定错过了我推荐使用聚合框架的解决方法的部分,我的答案的最后一部分提供了解决方案。
  • @chridam 我正在使用您建议的模式来存储班次,但被困在一个案例中,说我们有班次星 08:50 并在 20:30 结束,假设现在是 18:40,基于你的代码:` 1- "happyHours.startHour": { "$lte": hour }, 2- "happyHours.startMinutes": { "$lte": minutes }, 3- "happyHours.endHour": { "$gte ": hour }, 4- "happyHours.endMinutes": { "$gte": minutes } ` 它将通过第一个条件,因为 8 小于 18,但它会在第二个条件下失败,因为 50 大于 40 尽管在逻辑上是现实生活中的 08:50 早于 18:40
猜你喜欢
  • 2016-07-27
  • 1970-01-01
  • 1970-01-01
  • 2015-12-12
  • 1970-01-01
  • 2023-03-17
  • 2013-02-08
  • 2020-04-21
  • 2018-08-20
相关资源
最近更新 更多