使用Algolia进行可用性跟踪

13

我正在开发一个类似于Airbnb的网站,并且正在使用Algolia重写我们内部基于SQL的搜索系统。到目前为止,这真是一段非常愉快的旅程,因为我已经成功地消除了许多旧代码并进行了外包,取得了令人惊喜的结果。但是,我们搜索系统中有一个关键部分,我不确定是否可以使用Algolia实现。

在内部,我们将每个资产每个日期的可用性/不可用性(和价格)作为数据库中的单行存储。这意味着我们的availabilities表看起来像这样:

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
当用户搜索可用物业时,他们输入一个日期范围和可选的价格范围。
目前我们正在查询“availabilities”表,并确保日期范围内的所有日期都可用于该资产(即可用日期的计数等于范围内的天数)。如果用户输入了价格范围,我们还会确保这些日期的平均价格在所请求的范围内。SQL查询语句相当复杂,但归根结底就是这样做的。
我一直在尝试使用Algolia来复制这个功能,但是找不到任何关于类似功能的文档。实际上,我现在面临着两个单独的问题:
1. 我无法确保所提供的日期范围内的所有日期都可用,因为Algolia几乎没有关于关联的知识。 2. 我无法计算(和查询)所提供日期范围的平均价格,因为它取决于用户输入(即日期范围)。
有没有办法在Algolia中实现这一点?如果没有,是否可以使用SQL或其他工具与Algolia相结合以实现所需的结果?当然,我可以通过Elasticsearch做所有这些事情,但Algolia如此快速和简便,以至于我不想因为这些问题而离开Algolia。

你找到解决方案了吗?我非常好奇它是如何完成的。我随意浏览了一个房屋租赁网站,然后就想到了这个问题,现在我真的需要解决这个问题! - Rami Awar
1个回答

2

这个使用案例确实很复杂,Algolia需要预先计算的数据才能正常工作。


2020年编辑(更好的解决方案)

在每个项目中,您可以简单地存储位置可用的日期列表,例如:

{
  name: "2 bedroom appartment",
  location: "Paris",
  availabilities: ['2020-04-27', '2020-04-28', '2020-04-30']
  price_cents: 30000
}

在搜索时,您可以生成所需物品的所有可用性列表,例如(从4月28日到4月30日可用):

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 
}) 

在这个例子中,由于记录缺少“2020-04-29”,所以不会匹配。
另一种解决方案更通用,但需要更多的记录:
我假设您可以预订的提前天数有上限,在这里我假设为90天。您可以在这90天内生成所有可能的日期范围。这意味着要生成90 + 89 + ...= 90 * 91 / 2 = 4095个日期范围。然后对于每个范围和您在服务中提供的每个公寓,您都可以生成一个像这样的对象:
{
  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
}

使用这些对象,查找日期范围就像这样简单:
index.search('', {
  filters: '' +
    'availability_range:"' + startDate + ' -> ' + endDate + '" AND ' +
    'price_cents >= ' + lowPriceRange + ' AND price_cents <= ' + highPriceRange 
}) 

您需要索引可用的时间范围,这将大大减少对象数量,但仍可能非常庞大。

最后,对象中的时间戳将帮助确定哪些对象在预订时应删除。 调用方式类似于:

index.deleteByQuery('', {
  filters: 'availability_start_timestamp < ' + booking_end_timestamp + ' AND availability_end_timestamp > ' + booking_start_timestamp
})

很遗憾,我们存储了整个年份的可用性。我能否在Algolia之前或之后使用SQL进行过滤? - Alessandro Desantis
那么每个公寓你需要查看66795个日期范围,这可能会非常昂贵。 - Jerska
结果列表是否总是预期较低(<1000)?例如,您是否还受到位置的限制?如果是这样,您可以使用Algolia获取与文本+位置查询匹配的对象ID列表,并将此ID列表发送到MySQL以计算出此列表中可用的ID。 - Jerska
你可能会失去Algolia的速度,但仍然可以从其文本相关性中受益。 - Jerska
暂时来说,我们还不会有很多结果,但未来可能会有。这种解决方案的可扩展性如何?我可以采用哪些技术使它更具扩展性? - Alessandro Desantis
好的,一旦您的 Algolia 结果列表超过 1000 个项目,您可能会遇到困难。您可以将此限制增加一个数量级,但这并不是无限可扩展的。但我猜到那时,您会有专门从事该工作的资源。 :) - Jerska

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接