Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Availability tracking with Algolia

Tags:

search

algolia

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:

  • I have no way to ensure all dates in the provided date range are available, because Algolia has little to no knowledge about associations, and
  • I have no way to calculate (and query) the average price for the provided date range, because it depends on user input (i.e. the date range).

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.

like image 702
Alessandro Desantis Avatar asked Feb 09 '17 13:02

Alessandro Desantis


People also ask

What is Algolia used for?

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.

Is Algolia an API?

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.

How do you create an index in Algolia?

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.

How do you add data to Algolia?

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.


1 Answers

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
})
like image 162
Jerska Avatar answered Sep 29 '22 03:09

Jerska