贝壳找房 | 复杂订阅条件下,如何实时准确的向用户推送新上房源?

star2017 1年前 ⋅ 7420 阅读

卫海波@贝壳找房 贝壳产品技术

贝壳找房 APP 给用户提供了海量房源的搜索查询功能,但是网站存量房源并不能完全满足用户的找房需求,用户希望可以及时获取新上房源的实时提醒。目前贝壳找房 APP 提供的房源新上实时推送有两个维度:基于关注小区的房源新上和基于搜索订阅条件的房源新上。

基于关注小区的房源新上只能给用户推送关注小区的新上房源,覆盖小区有限,而且用户买房时,在关注小区之前通常是通过筛选条件锁定某区域范围、某价格区间、某面积区间之类的房源。基于搜索订阅条件的房源新上恰好给用户提供了该场景下的房源新上的通路。

本文将重点讲解如何实现基于用户搜索订阅条件的房源新上实时推送方案。

1 核心难点

解决房源新上实时推送给订阅搜索条件用户,核心难点在于当一个房源上架时,如何在海量复杂的用户订阅条件中快速找到哪些用户的订阅条件能命中该房源。

如图 1 所示,贝壳找房 APP 给用户提供了各种筛选项,从区域地铁、价格、面积、标签等等。同类条件可以多选,不同类条件可以随意组合,这些筛选项可以组合出复杂多变的筛选条件,用数学的排列组合来计算,每一类条件的排列组合是 A=C(a,1)+ C(a,2)+…+C(a,a) , 而不同类的条件组合是 SUM=A * B * … * N,仅以北京为例,假设同类条件只选择一个,即 A= C(a,1),那么 SUM≈153 亿种条件组合。目前贝壳 APP 的用户已经选择了约 500 万条件作为自己的搜索订阅条件,且持续增长中。

面对如此海量且复杂的搜索订阅条件,当一个房源新上时,如何快速找到哪些用户的搜索条件与该房源有关并且推送给用户,是该方案要核心解决的难点问题。

图片

图 1. 贝壳找房筛选条件选项

2 产品功能介绍

在介绍方案之前,先看一下产品形态。当用户通过选择某些条件来筛选房源并且订阅该搜索条件,比如订阅条件是“北京市 944-1416 万二室”,如图 2:

图片

图 2. 用户搜索房源并订阅搜索条件

当北京市房源新上时,比如该房源属性是 980 万 2 室,符合上述用户订阅的条件“北京市 944-1416 万二室”,则实时推送给该用户。如图 3:

图片

图 3. 房源新上推送给符合订阅条件用户

用户点击 PUSH 进入推送消息落地页,可以及时查询房源信息,可与经纪人进行及时沟通。如图 4:

图片

图 4. 符合用户订阅条件的实时 feed 流

由以上场景可以看出,用户订阅了”北京市 944-1416 万二室“搜索条件,当北京新上了一套 980 万 2 室 70 平米的房源,满足了该用户订阅的条件,则实时给用户进行了推送。

3 解决方案

贝壳找房 APP 房源筛选功能是通过用户搜索条件召回房源,而房源新上推送是通过房源召回检索条件,这两个场景虽然是相反的关系,但是也有相通性。在介绍基于房源召回搜索条件之前,先介绍贝壳找房 APP 是如何基于用户搜索条件召回房源的。

3.1 基于搜索条件召回房源

3.1.1 搜索条件描述

贝壳找房 APP 给用户提供了多种类别的筛选条件(此图位贝壳找房网页、APP 条件跟这个相同),如图 1 所示。从图 1 可以看出,贝壳找房 APP 提供的筛选种类丰富,包含了地理位置、房源价格、面积、特色标签、楼盘属性等筛选类别。基本可以涵盖用户的房源筛选需求,所有这些条件都可以进行组合筛选。

在实现上,我们给每类条件的每个选项一个唯一标识,每个 item 用“字母 +id”的形式表示。

比如东城区用 d23008614 表示,其中 d 代表城区、23008614 是该城区的唯一 id,价格是 p、面积是 a、房型是 l,对于这种没有楼盘属性的词,业务则自己分配 id,按照基础数字递增,比如 200 万以下:p1,一室:l1,50 平米以下:a1。

通过这种组合,用户在筛选各种条件后,将每个 item 条件进行拼接,则组成用户的筛选条件。比如用户的搜索条件是 d23008614l3p5,即为用户搜索”东城 3 室 400-500 万”的房源。服务端保存的用户订阅的条件也是“d23008614l3p5”该值。

3.1.2 房源属性数据结构描述

上一小节我们描述了用户的条件组成,本节介绍一个房源的唯一描述。每一个房源有自己单独的唯一属性,比如地理位置信息、价格、面积等等,我们通过不同字段对房源进行描述,并建立房源的数据结构。最后将该房源的数据结构存储在 ES 索引里。

我们设置一组通用的字段描述,如果该房源无该属性,则填充默认值为 NULL 即可。房源属性字段描述如下:

图片

3.1.3 搜索条件召回房源

在 3.1.1 小节中,用户搜索完一个条件,选中的条件比如是 d23008614l3p5,后端拿到该条件进行解析成房源属性对应的字段分别为:

图片

后端解析完之后转成对应的检索查询条件,如下:

图片

通过以上检索语法就可以召回用户条件“d23008614l3p5”命中的房源,即实现了用户搜索条件召回房源的功能。

3.2 基于房源召回订阅条件

在没有基于房源召回订阅条件之前,我们的基于订阅的房源新上推送是采用以下传统的搜索订阅房源新上推送方式。

3.2.1 传统的搜索订阅房源新上推送

在 3.1 我们介绍了基于搜索条件召回房源,传统的基于搜索订阅新上房源则采取如下方案:

图片

图 5. 传统搜索订阅推送方案

该方案虽然可以实现符合用户订阅条件的房源新上推送,但是也有着很明显的缺点,主要有以下几个方面:

图片

3.2.2 基于房源新上实时召回订阅条件

基于房源召回命中的订阅条件与 3.1 是相反的,借鉴 3.1 索引的思路,我们采取以下方案来实现房源召回命中的订阅条件。

图片

图 6. 实时订阅索引构建和房源新上实时推送

图片

在 3.1.1 中我们可以看到目前贝壳 APP 提供的搜索筛选项,3.1.2 我们看到了房源字段的描述。我们借助这两个维度信息,用以下这些字段来描述一个用户的搜索条件。

如果用户选择了该选项,则字段值为用户实际选择的条件值,如果用户没有选择该选项,则给默认值-1。

图片



我们将用户的选择的条件主要分为以下两类:

(1)有限枚举集合:比如城区、商圈、朝向等等,这种条件直接填充用户选择的值即可,如果用户没有选择该条件,则填充-1,代表用户未选择该条件,比如用户选择东城满五房源,可以用以下字段描述:

图片

(2)对于价格和面积这类不确定区间范围字段产品给用户提供两种选择:

方式一:有限可枚举区间段,比如 400-500 万,600-700 万,1000 万以上,区间段用户可以间隔选择多个。

区间段有个分界值,比如价格是 1000 万,即 1000 万以下是有多个区间段组成,而 1000 万以上就只有一个 1000 万以上选项。

方式二:用户自定义输入一个区间,比如 123-789 万或者 800-2000 万

这两种方式中,用户只能选择其中一种方式进行筛选,面积也同理。

针对像价格面积存在有限区间段且可以间隔选择以及无限区间的情况,我们设置三个字段来标识用户的条件,以价格举例,分别是 priceEnum、priceMin、priceMax。priceEnum 主要解决分界值以下价格区间段选择存在断档可能,priceMin、priceMax 主要解决超分界值自定义区间。

图片

该三个字段涵盖了用户关于价格的所有筛选场景,主要有以下三种描述:

  1. 当用户没有选择价格时:

图片

  1. 当用户选择的价格,且价格没有超过分界值,比如选择了 200-300 万,400-500 万:

图片

  1. 当用户选择了价格,且价格超过了分界值,比如选择了价格区间,比如 800-1200 万:

图片

面积的原理同上,分别是 areaEnum、areaMin、areaMax,分界值是 200 平米。

通过以上工作,我们将用户的搜索条件转换成房源维度的索引信息,比如一开始的用户订阅条件 ”944-1416 万,2 室“ 搜索条件转化为索引信息如下:

图片

将转换完的订阅条件存储到用户的订阅条件索引里。

接下来到了方案最后一部分,当房源新上时,如何从用户的订阅条件索引里召回符合条件的数据。

当一个房源新上时,通过 3.1.2 获取房源的属性字段,然后在 3.2.1 构建的用户订阅条件中查询,查询方式如下:

  1. 除了价格、面积的其他字段,比如该房源卧室数量为 2,则查询如下:

图片

该查询是即为查询用户订阅条件中的 bedroomNum 包含为-1 或者 2,意味着用户订阅条件中没有选择卧室条件或者选中卧室条件包含 2 室。其他条件类似。

  1. 价格、面积类,因为涉及到枚举字段和最小值、最大值方式。

如果房源价格为 980 万,在价格分界值 1000 万以下,则查询条件如下:

图片

该查询是即为查询用户订阅条件中的 priceEnum 值包含-1 或者 980,意味着用户订阅条件中没有选择价格条件或者选中价格条件包含 980 万。

如果房源价格为 1299 万,在分界值 1000 万以上,则查询条件为:

图片

该查询即为查询用户条件中最小价格小于等于 1299,最高价格大于等于 1299(因为如果用户没有选中价格条件的话,priceMin=0,priceMax=2147483647 也满足此条件)。

通过以上的分析,当一个房源新上时,通过获取房子字段的标准信息值,查询用户的订阅条件索引的语法如下:

图片

通过以上查询,可以获取到符合该房源的用户订阅条件,然后直接推送给用户即可。而一次查询只需要 200ms 左右的时间。基于以上方案,我们就实现了基于用户订阅条件的房源新上实时推送方案。

该方案巧妙的应用了 ES 的查询功能,将用户的搜索条件转换为与房源关联的数据结构,当房源新上时,实现了通过房源反查命中哪些用户的订阅条件,快速实现了消息实时推送。

相对于传统的搜索订阅推送,该推送方案有如下优点:

图片

以上只是 C 端信息服务的其中一部分内容,在贝壳 APP 中,用户可以搜索房源、浏览信息、与经纪人沟通。这些都是基于用户主动去获取信息。而 C 端二手搭建的信息服务则是通过用户在平台行为,通过技术手段将房源的信息变更实时触达给用户,让用户享受到贝壳 APP 提供的及时信息服务。

下图是 C 端二手信息服务架构图:

图片

图 7. 信息服务架构图

该信息服务核心在于基于用户在平台的行为,将房源变更信息实时触达用户的能力。核心要解决以下几个问题:

(1)如何实时捕捉房源的信息变更。

(2)如何实时获取房源变更应触达哪些目标用户。

(3)如何支持产品的各种触达策略、包含优先推送、聚合推送、频次限制等。

(4)如何在每日千万级数据中保证及时推送。

本文章主要针对以上第二点遇到的一个问题做了一次方案的讲解,在服务搭建过程中,我们团队还解决了其他的难点问题、比如如何保证房源变更信息的时序性、如何对消息进行聚合推送、如何在实体维度、用户维度、公众号维度进行推送频次限制等等。

该信息服务未来将着力于接收更多房源、小区以及其他信息变更,将着力于支持更多用户在平台的订阅行为。让贝壳 APP 的用户享受到贝壳平台提供的信息服务。也希望大家可以共享共建。

贝壳 C 端团队一直致力于更好的服务用户,搭建高品质 C 端平台,帮助用户找到满意的房源。贝壳 C 端是承载用户、经纪人、房源的核心载体,不仅需要帮助用户找到更满意的房源、也需要让更多的经纪人与用户进行连接。贝壳 C 端团队实现使命的同时也遇到很多难点问题。比如如何快速高质量实现产品功能;如何连接海量用户、房源、经纪人;如何应对高并发时保证服务稳定性等等。有些难题已经解决,还有些难题等着我们去发现和攻克。欢迎对贝壳 C 端感兴趣的同学加入我们(简历可发送至:webapi@lianjia.com),让我们一起打造产业互联网的第一 C 端,共建品质居住平台。


本文地址:https://www.6aiq.com/article/1611957959517
本文版权归作者和AIQ共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出

更多内容请访问:IT源点

相关文章推荐

全部评论: 0

    我有话说: