How to search by duration in Algolia


Let's say I am building a hotel booking platform, and every Room record has availability calendar. A common search criteria is to search by duration. Where user inputs start date and end date, and database fetches rooms that are not occupied from that duration.

I have implemented a very naive approach where I store the occupied days as an array of days.

attribute :occupied_at_i do
    array = []
    if !occupied_at.empty?
        occupied_at.each do |date|
            array << Time.parse(date).to_i
        end
    end
    array
end

And then at the client side, I add the following javascript code to cross-check if the day is in the numericRefinement

// Date Filters
$('.date-field')
    .on('change', function() {
        if(_.every(_.map($('.date-field'), function(date) {return _.isEmpty(date.value) }), function(n) {return n==false;})) {
            helper.clearRefinements('occupied_at_i');
            var arrayOfDates = addDateFilters();
            _.forEach(arrayOfDates, function(n) {
                helper.addNumericRefinement('occupied_at_i', '!=', n);
            });
            showClearAllFilters();
            helper.search();
        }
    });

So, it obviously is not a good way to do it, I am wondering what's a better to leverage on algolia and search by duration?

Thanks

Hope this helps others (since question has asked long back)

it is always better do the filtering at server side and render the results. Here one approach would be to add datetime fields to Room model as start_date and end_date. So that when user inputs start date and end date, records are fetched based on occupied status in that duration. One simple query would be like:

Room.where.not("start_date >= ? AND end_date <= ?", start_date, end_date)

The other best solution would be like to have another model to save Room Bookings details with start and end datetime fields. This way we can have multiple room bookings for a particular room and it can be saved simultaneously in the room booking collection. Hence the query would become:

Room.left_joins(:room_bookings).
  where(
    "room_bookings.start_date > ? OR
     room_bookings.end_date < ?", end_date, start_date
  )