Mongodb处理营业时间以及如何找到我们的地方是否开放

时间:2015-10-04 16:31:45

标签: mongodb

我正在努力寻找处理餐厅营业时间的最佳方式。复杂性是由于:

  • 地方可在同一天多次开放(例如7:00-14:30,18:30-22:00)
  • 有时结束时间超过午夜(例如19:00-2:00)
  • 不是每天都有相同的时间

因此,一种好的方法似乎是在每周的每一天注册打开/关闭时间的数组,格式为:seconds since the beginning of the week。这是一个例子

{
    "address": "street 1, city, postcode",
    "hours" : {
        "mon" : [
            {
                "opened" : 25200, // 07:00
                "closed" : 52200 // 14:30
            }
        ],
        "tue" : [
            {
                "opened" : 111600, // 07:00
                "closed" : 138600 // 14:30
            },
            {
                "opened" : 153000, // 18:30
                "closed" : 180000 // 02:00 (of the day after)
            }
        ],
        ...
    }
}

(在模型中我有一个使用a small piece of code I wrote渲染的静态变量来为每个字段执行自动下拉)

在我看来,整周的开放时间如下:

Monday: {{#each hours.mon}}
    {{#if @index ">" 0}}<br />{{/if}} // this just breaks the second array item in a new line
    {{getOpeningTime opened}} - {{getOpeningTime closed}}
{{/each}}
<br/>
Tuesday: ...

getOpeningTime是一个模板助手,使用moment.js以HH:mm格式返回时间:

getOpeningTime: function(seconds) {
    return moment().startOf('day').seconds(seconds).format('HH:mm');
}

到目前为止一切都很好 - 尽管我仍然不确定这是否是正确的方法

现在,我正在尝试注意用户在他/她正在查看页面时是否打开了餐厅。这是我到目前为止所写的内容:

openedOrClosed: function() {
    now = moment();
    ddd = now.format('ddd').toLowerCase(); // I now I will look into the field hours.day - the first three letters all lowercase

    day = now.day();
    day = (day === 0 ? 7 : day); // This is just a conversion I do because I want to have Sunday at the end of the week

    seconds = now.clone().diff(now.clone().startOf('day'), 'seconds') + (86400 * day) - 86400; // Minutes since midnight in Momentjs (http://stackoverflow.com/a/25390707/1435476) plus the sum of all the other days of the week to work out the global seconds since the beginning of the week

    query = {};

    query._id = this._id;

    // here I have available all I need. but I'm not sure how to build the query

    if (Restaurants.find(query).count() > 0) {
        return "Opened";
    } else {
        return "Closed";
    }
}

2 个答案:

答案 0 :(得分:1)

首先:处理日期和时间是一项挑战:)。

我认为自本周开始以来你的秒数很长。格式是没有必要的。 Momentjs现在可以解析&#39;白天和小时(以及更多)。

您还应该考虑圣诞节等异常情况。除此之外,餐厅可以每天多次开放(例如9到2,以及5到11)。

我会选择这样的事情:

restaurantname:{
     //special days array of objects
      specialdays: 
           [{date: date, 
             openinghours: 
            //again array of objects
                  [{start: sometime, end: sometime},
                   {start: somtime, end: sometime},
                   //etc
                   ]
             }]
            },

        normaldays: {mon: //openinghours like above, again array of objects with start and end, tue, wed etc}

之后你可以先检查一下:这是特殊的一天吗?如果是=&gt;检查当前时间是在开始之后还是在结束之前(循环对象数组)。 否则,如果不是特殊的一天,请检查特定的正常日期&#39;并做同样的事。

我认为转换是理想的。你可以从具体的一般开始,使你的病情首先落在特定的病例。

这只是一个大纲,我知道它具有挑战性:)。

希望这会有所帮助......

答案 1 :(得分:1)

你走了,

var days = ['MakingIndex1ForMonday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday' ];
var query = {};
query._id  = this._id;
query.dayName = days[now.day()];

if (Restaurants.find({
_id : query._id,
'hours.' + query.dayName.closed : {$lte : seconds},
'hours.' + query.dayName.opened : {$gte : seconds}
}).count() > 0) {
    return "Opened";
} else {
    return "Closed";
}

我在mongoshell中使用您提供的数据进行了查询,
so是此处的集合名称,160000&amp; 190000是以秒为单位的测试值

根据需要返回1行

db.so.find({'hours.tue.opened' : {$lte : 160000}, 'hours.tue.closed' : {$gte : 160000}})

这会根据需要返回空集#又为0行

db.so.find({'hours.tue.opened' : {$lte : 190000}, 'hours.tue.closed' : {$gte : 190000}})

顺便说一句,我喜欢你的实现,只需几秒钟,它就更容易管理。如果你再次卡在某个地方我将只在这里