Check if current date between two dates in french MongoDB aggregation

I have a collection of restaurant documents in my MongoDB database with an hours field having the format below.

How can I check if a restaurant is open now using MongoDB aggregation?

My hours field has data like this (with french days):

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

Hello @Mehdi_Khlifi,

You can try the following. As such the present hours data is awkward to work with, and suggest change the way you store your data (I have a suggestion at the bottom of this post).

The query runs from mongo shell. Let me know how this worked for you.

var WEEK_DAYS = [ "Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi" ];
var now = new Date();
var HH_MM = now.getHours()*100 + now.getMinutes();
var WEEK_DAY = WEEK_DAYS[now.getDay()];

db.collection.aggregate([
{ 
    $addFields: { 
        isOpen: { 
            $filter: { 
                input: { $objectToArray: "$hours" }, 
                as: "e", 
                cond: {
                    $and: [ 
                        { $eq: [ WEEK_DAY, "$$e.k" ] },
                        {
                            $let: {
                                vars: {
                                    start_hr: { $arrayElemAt: [ { $split: [ { $arrayElemAt: [ "$$e.v", 0 ] }, ":" ] }, 0 ] },
                                    start_min: { $arrayElemAt: [ { $split: [ { $arrayElemAt: [ "$$e.v", 0 ] }, ":" ] }, 1 ] },
                                    end_hr: { $arrayElemAt: [ { $split: [ { $arrayElemAt: [ "$$e.v", 1 ] }, ":" ] }, 0 ] },
                                    end_min: { $arrayElemAt: [ { $split: [ { $arrayElemAt: [ "$$e.v", 1 ] }, ":" ] }, 1 ] },
                                },
                                in: {
                                    $and: [ 
                                        { $gte: [ HH_MM, { $toInt: { $concat: [ "$$start_hr", "$$start_min" ] } } ] },
                                        { $lte: [ HH_MM, { $toInt: { $concat: [ "$$end_hr", "$$end_min" ] } } ] },
                                    ]
                                }
                            } 
                        }
                    ]
                }
            }
        }
    }
},
{ 
    $addFields: { isOpen: { $gt: [ { $size: "$isOpen" }, 0 ] } }
}
])

The result will have the isOpen field value either true or false.

The following is a format to have the hours field in the collection and the query will be simpler:

hours: [
  { weekday: "Lundi", start: "10.30" end: "23.00" },
  { weekday: "Mardi", start: "08.00" end: "22.30" },
   ...
]

I’m not sure the current way things are stored are a problem - as long as the query can get the current day of the week in appropriate format… but the client should be able to do that before generating the query. (You could do it by getting it from current date the way @Prasad_Saya shows but there are other ways).

dayOfWeekNow="Jeudi";  /* this would be instead populated in whatever language based on today */
currentHour="11:34"; /* current time as a string in same format as hours stored */
/* match restaurants that are open */
filter={};
filter["hours."+dayOfWeekNow+".0"]={$lt: currentHour};
filter["hours."+dayOfWeekNow+".1"]={$gt: currentHour};

Now db.coll.find(filter) will match documents that have open hours on given day.
If you wanted to return only the matching fields in the found documents just add a projection:

proj={};
proj["hours."+dayOfWeekNow]=1;
db.coll.find(filter, proj)
{ "_id" : ObjectId("61324fa9bba8077232b099e2"), "hours" : { "Jeudi" : [ "08:00", "23:00" ] } }

Asya