I am working on an Airbnb-like website and I am in the process of rewriting our in-house, SQL-based search system with Algolia. It's been a really pleasant journey so far, as I have managed to remove a lot of legacy code and outsource it, with awesome results. However, there is one critical piece of our search system which I am not sure can be implemented with Algolia.
Internally, we store the availability/unavailability (and price) of each date for each asset as a single row in the database. This means our availabilities
table looks like this:
asset_id | date | status | price_cents
-------- | ---------- | ----------- | -----------
1 | 2017-02-09 | available | 15000
1 | 2017-02-10 | available | 15000
1 | 2017-02-11 | unavailable | NULL
1 | 2017-02-12 | available | 20000
When a user searches for available properties, they enter a date range and, optionally, a price range.
What we're doing now is simply querying the availabilities
table and making sure that all dates in the date range are available for that asset (i.e. the count of available dates is equal to the number of days in the range). If the user enters a price range, we also make sure that the average price for those dates is within the requested range. The SQL query is fairly complex, but this is what it does at the end of the day.
I have been trying to replicate this with Algolia, but couldn't find any documentation about a similar feature. In fact, I am facing two separate issues right now:
Is there a way to achieve this with Algolia? If not, is it feasible to use SQL or another tool in combination with Algolia to achieve the desired result? Of course, I could do all of this with Elasticsearch, but Algolia is so fast and easy that I'd hate to step away from it because of these issues.
Algolia is an AI-powered search and discovery platform for dynamic experiences that helps businesses maximize the speed of search and discovery, while solving the pain of relevance tuning through AI. Accessing the right content or products on websites and apps has never been faster or more intuitive.
The Search REST API is the core of Algolia Search. Around it, Algolia built a complete ecosystem, of libraries, tools, and a dashboard. You should use the official API clients and libraries to implement Algolia. They're all open source, and the code is available on GitHub.
You don't need to create an index explicitly: Algolia creates it automatically the first time you add an object. If you wish to configure your index, the settings section provides details about advanced settings. Since index objects are schemaless, you don't need any pre-configuration to start indexing.
If you're adding records to an existing index, you can click Add records > Upload file instead. Drop the file into the Upload records box or click and select it on your file system. Then, click Upload. Once Algolia has indexed your data, the dashboard sends a notification indicating a successful save.
This use-case is definitely complex, and Algolia needs precomputed data in order to work.
Edit 2020 (better solution)
In each item, you could simply store the list of days where the location is available, e.g.
{
name: "2 bedroom appartment",
location: "Paris",
availabilities: ['2020-04-27', '2020-04-28', '2020-04-30']
price_cents: 30000
}
You could then, at search time, generate the list of all the availabilities you require your items to have, e.g. (available from April 28th to April 30th):
index.search('', {
filters: '' +
'availabilities:2020-04-28 AND availabilities:2020-04-29 AND availabilities:2020-04-30 AND ' +
'price_cents >= ' + lowPriceRange + ' AND price_cents <= ' + highPriceRange
})
In this example, the record wouldn't match as it lacks 2020-04-29
.
Another solution, which works more generically, but requires way more records:
I'm assuming there is a cap of the amount of days in advance you can book, I'll assume here it's 90 days.
You could generate every date range possible inside those 90 days.
This would mean generating 90 + 89 + ...
= 90 * 91 / 2
= 4095
date ranges.
Then for each of those ranges, and each of the flats you're offering on your service, you could generate an object like this:
{
name: "2 bedroom appartment",
location: "Paris",
availability_range: "2017-02-09 -> 2017-02-10",
availability_start_timestamp: 10001000,
availability_end_timestamp: 10002000,
price_cents: 30000
}
With those objects, then searching for an date range would be as easy as:
index.search('', {
filters: '' +
'availability_range:"' + startDate + ' -> ' + endDate + '" AND ' +
'price_cents >= ' + lowPriceRange + ' AND price_cents <= ' + highPriceRange
})
You would only be indexing available time ranges, so this should greatly reduce the amount of objects, but it would still be probably huge.
Finally, the timestamps in the object would be here to know which ones to delete when a booking is made. The call would be something like:
index.deleteByQuery('', {
filters: 'availability_start_timestamp < ' + booking_end_timestamp + ' AND availability_end_timestamp > ' + booking_start_timestamp
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With