Hybris电商平台搜索服务实践

电商平台搜索服务特点

随着电商平台的快速发展和所销售商品的数量大规模增长,从大量的商品数据中快速获取用户关注的商品,变得越来越有挑战性。优秀电商平台能够吸引客户的因素之一,就是拥有强大,友好的搜索服务,用户能够从大量数据中快速找到想要的商品。

这里写图片描述

图1-1 搜索功能演示

搜索引擎需要解决如下问题:

  • 相关的商品能不能在一秒甚至更短的时间返回
  • 对用户输入的关键字进行错误检查
  • 当用户输入关键字的时候,给予一些关键字的建议
  • 返回包含与关键字匹配的同义词的商品
  • 对一些匹配度高但没有实际意义的词进行过滤,比如“a”,“an”,“of”等
  • 根据相关度进行排序

目前搜索的开源方案已经非常成熟,针对以上问题都有相应的解决方案,最出名的Solr和Elastic Search都是基于Lucence的。 Hybris电商平台使用Solr作为自己内嵌的搜索解决方案。本文将以一个B2C家用电器垂直电商为业务背景,基于Hybris平台,讨论如何使用Solr的特征定制出强大的搜索方案,进一步提升用户的搜索体验。需要注意的是,Hybris平台对Solr做了一系列的封装,本文不会对Solr具体的API展开讨论,有兴趣的读者可以查阅Solr官网

基于Hybris的搜索服务体系架构

Hybris电商平台一般将商品数据存储到关系型数据库如MySql,Oracle中,而Solr是一个NoSQL的搜索技术,要使用Solr,就是要把关系数据库中的商品数据,转换成Solr支持的NoSQL结构的Document,添加到Solr中去,并创建索引。

架构设计面临的挑战

结合垂直电商的业务特点,在Hybris中使用Solr实现搜索服务会面临以下挑战。

1. 基础架构设计

一个完整的Hybris电商平台由多个不同角色的服务器组成。比如提供页面的web 服务器,后台用户使用的Backoffice服务器,提供搜索服务的Solr服务器,执行后台定时任务的Job服务器等。应该考虑如何将Solr服务器与其他服务器组织到一起,提供高可用,可扩展的搜索解决方案。

2. 数据过滤

家电行业电商中一般销售的商品有实体电器如冰箱,洗衣机,电器配件如安装螺丝,天然气管,虚拟商品如安装服务,延保服务等。应该考虑哪些商品,商品的哪些属性需要添加到Solr中去,那些商品和属性不需要添加到Solr中去。从而减少文档数量和大小,提高查询效率。

3. 添加数据到Solr的方案

电商平台数据库中的商品数据,经常会有更新。应该考虑一种健壮的数据同步方案,用来处理全量数据和更新数据从关系数据库到Solr服务器的迁移。

4. 平台化统一接口

Solr提供类似REST 风格的API,但作为一个电商平台,应该根据自身业务对Solr的接口进行进一步封装,从而提供一些针对自身特定业务的API接口。

下文将对这些挑战一一进行讨论并给出解决方案。

基础架构设计

Solr支持Master-Slave和SolrCould模式。Master-Slave模式的优点在于配置简单,易于维护。针对数据量和访问量不是特别大的垂直电商,非常适用。如果访问压力过大,通过简单的添加Slave节点即可缓解。然而,当数据量到了一定程度,单台服务器的访问速度会急速下降。如果Master节点宕机,更新数据的索引操作会失败,只能由Slave节点继续提供查询服务。产品量巨大,对搜索性能和高可用性要求更高的场景,建议使用Solr Cloud的方式搭建服务器。

笔者所在的项目是一个销售家用电器的垂直电商网站,商品数量有两万多个,需要存到Solr中的小于一万个,所以选择使用Master-Slave模式来提供搜索服务。Master节点只负责商品的添加和索引,通过Hybris定时任务服务器从关系数据库读取商品数据, 添加到Master节点中去。多个Slave节点用来提供查询服务, 定时从Master节点复制数据, 每个Slave节点的数据是一致的。并在Solr API 的基础上,根据电商业务对Solr API进行封装,提供统一的调用接口,通过Hybris Web服务器来提供搜索服务。具体架构见图2-1。

这里写图片描述

图2-1 Master-Slave 模式的部署方案

搭建Master-Slave模式,需要分别在Master节点和所有Slave节点的solrconfig.xml里面进行如下配置。

这里写图片描述

图2-2 Master-Slave 模式的配置

通过配置pollInterval,Slave节点经过一定的时间间隔,去Master上同步一次数据,从而实现数据的一致性。时间间隔的设定建议参照Master节点的更新频率,比如Master节点十分钟更新一次的话,建议Slave节点对十分钟读取一次Master,从而达到数据的一致性。

商品数据过滤

为了提高查询速度,可以从业务角度出发,对商品数据进行过滤。毋庸置疑,实体商品家电是要添加到Solr中去。电器配件,安装服务和延保服务等商品,如果只能和实体家电捆绑销售,是不需要添加到Solr中去的。一方面这些商品不能单独销售,用户不应该能搜索出来这些类型的商品。另一方面可以减小Solr Document数量,从而提高查询效率。

还应该考虑商品的哪些属性需要添加到Solr中去。家电商品的属性一般有编号、名称、描述信息、价格、颜色、尺寸、生产厂商、销量、功率等。需要添加到Solr中,通过查询返回给用户的属性,一般分为三类。有些属性会属于一到多个类别。

  1. 和用户搜索关键字进行匹配的属性如编号,名称,描述信息等。
  2. 排序需要的属性如价格,销量,好评等。
  3. 分组统计需要的属性如颜色尺寸,价格,品牌,功率等。

其他不需要的属性建议不要添加到Solr中去,这样可以减小Document本身的大小,提高网络传输速度。 添加到Solr的属性,一般是那些读取频率高而修改频率低的属性,避免过度更新Solr而带来的性能问题。比如,库存信息不适合添加到Solr中去,这个数字要求实时准确的显示,如果库存变动过快而频繁更新Solr的话,会引起搜索性能的下降。建议实时读取库存数据。

添加数据到Solr方案

添加商品到关系数据库和Solr,常规的做法一般有两种。

  1. 从数据源读取数据,同时添加到数据库和Solr。这种做法的好处是,数据库和Solr中的数据保持一致。缺点是两种系统使用不同的数据格式和导入方案,系统集成和保持数据一致性会相对复杂。
  2. 从数据源读取数据,先将商品添加到数据库,然后再从数据库读取数据,添加到Solr。这种做法的好处将导入方案一分为二,分别实现,灵活性高。缺点是数据库和Solr存在短时间的数据不一致。

Hybris选择第二种方式来实现商品的添加。允许短时间数据库和Solr之间数据的不一致性。通过DataHub将商品添加到数据库不在本文讨论范围之内。下面针对从数据库读取数据,添加到solr中进行详细讨论。

从数据库将商品添加到Solr分为两种情况,全量数据的添加和更新数据的添加。

全量数据添加是指一次性将数据库中所有符合条件的商品添加到Solr中去。这种方式适合有新商品添加到数据库但还不在Solr中的情况。

更新数据添加是指将数据库的某些属性已经更新的商品添加到Solr中。这种方式适合商品已经在Solr中,但数据库中此商品属性值发生变化的情况。需要把这些有更新的商品以增量的方式添加到Solr中。

针对以上两种情况,Hybris平台提供了两个对应的定时任务去把商品数据转换成Document并添加到Solr中去。为了方便讨论,将全量数据添加定时任务命名为full-electrics-cronjob, 将增量数据添加定时任务命名为update-electrics-cronjob. 这两个定时任务的执行流程如下图所示。

这里写图片描述

图2-3 定时任务执行流程

触发器

根据自己商品数据的更新特点,来设置对应定时任务的执行频率,默认配置在solrtrigger.impex 中。如果频繁有新商品添加到数据库,建议将全量数据导入的定时任务full-electrics-cronjob设置为每天更新一次,时间建议放到凌晨,那个时候对搜索服务性能影响最小。如果某些商品的属性变化比较频繁,那么可以设置添加更新数据的定时任务update-electrics-cronjob每十分钟执行一次,从而快速将数据库更新同步到Solr中去。频繁添加数据到Solr中,会引起Solr查询效率的降低。应该综合考虑数据本身的更新的频率,允许短时间内搜索引擎和数据库中数据的不一致等方面, 给定时任务设置出一个比较合理的触发频率。如果商品添加或者属性更新没有规律可循,可以禁止触发器,由后台管理员按需手动触发定时任务。

这里写图片描述

图2-4 设置定时任务执行频率

查询语句

提供定时任务需要执行的从数据库查找商品的query, 默认情况下,query的配置在solr.impex中。为了简化搜索的query,建议给商品的模型上面添加一个searchable的属性,在数据库中将配件,延保服务,安装服务的商品searchable设置为false。根据家电行业的业务规则,我们创建的queries如下。

这里写图片描述

图2-5 设置两种查询语句

读取商品的指定属性

Hybris平台提供了一套完整的添加机制,并且默认把商品的一些基本属性如编号,名字,描述信息等添加Solr,我们只需要把自己扩展的商品属性添加。默认配置在solr.impex中。如果需要导入的属性名和Product对象的属性名一样,并且不需要特殊的业务处理,则不需要添加value provider. 如果要导入的属性里面有业务逻辑处理,则需要添加value provider,比如下图中description是Product的一个属性,不需要提供value provider。 priceValue 是从PriceRow中获取的,则需要提供value provider.

这里写图片描述

图2-6 如果属性需要做分词处理,type为text。按照原值存储,type为基础类型

平台化查询接口设计

Solr支持类似REST API,根据电商系统的特点,Hybris对solr 查询API 进一步封装,创建一个适合电商业务的平台化查询接口。如提供根据Category查询商品的API,根据用户输入关键字进行查询的API,根据用户输入关键字返回自动建议的API等。

这里写图片描述

图2-7 查询接口

基于Hybris 的搜索服务实践

Solr提供了一系列的高级特征如分组统计,搜索结果归类等。应该考虑怎么将这些特征和B2C电商的业务特点结合起来,进一步提升用户体体验。并且考虑哪些页面需要从Solr中读取数据,哪些页面从数据库中读取数据。

商品列表页面PLP

这个页面不需要用户输入关键字,而是通过指向不同category的URL,直接从Solr搜索当前category并返回商品。图3-1是一个典型的PLP页面,使用到了Solr的返回结果归类, 分组统计和排序功能。

商品细节展示页面PDP并不适合从Solr服务器中读取数据,因为PDP会展示当前产品的所有详细信息,一方面这些信息不一定会存储到Solr中去,另一方面很多信息需要显示最新值,如库存等。建议PDP页面直接从数据库读取商品信息。

这里写图片描述

图3-1 通过读取Solr返回内容的PLP页面

搜索结果归类(Result grouping)

搜索结果归类功能可以把搜索到的同一类型的商品按条件进行归类,减少返回的document数量,在页面上将同类型商品显示在一块,从而减少用户看到大量相同或相似的东西。比如一个销售电器的平台,某种冰箱有多个颜色,那么理想的方式是把同款不同色的冰箱归类成一个返回。如图3-1 相同型号不同颜色的冰箱在一个格子显示,通过点击颜色图片,进行信息切换,方便用户查看。

Hybris电商平台把Solr的这一特性,封装成了一个对象,只要提供归类的参数,即可实现这个功能。如果相似的商品只返回一个Document的话,这个Document里面需要包含其他类似商品的需要显示的基本信息,要不然其他商品的信息无法得到。

Hybris提供了一个SolrIndexdType 对象,可以在里面设置分组方案。比如下图按照商品的baseProductCode进行分组,返回个数是1个,支持groupFacets。

这里写图片描述

图3-2 在impex设置group的策略

分组统计功能可以将返回的商品,按照某个属性进行分组。比如搜索出来一组冰箱,可以按照冰箱的价格区间,样式,颜色等不同的属性组分类,方便用户选择。图3-1 左边的checkbox,就是按照商品的不同属性而做的分组,点击checkbox,右边商品会按照左边的条件进行过滤。Hybris对分组统计的查询语法进行了封装,只需要通过impex中指定当前商品属性的facet 为true即可。

这里写图片描述<、center>

图3-3 设置商品的color等属性的facet为true

搜索结果排序(Sorting)

一般的排序方式有按照相关度,名称,价格等。Hybris对Solr的排序功能进行了一系列封装,默认配置在solr.impex 里面。在SolrSort 中来配置需要排序的方式,然后再SolrSortField中配置需要用来排序的字段和升降序。

这里写图片描述

图3-4 通过在impex配置来实现排序功能

搜索框和搜索结果页面

一般电商网站会在页面的头部提供查询搜索框,这个查询框将用户输入关键字发送给Solr服务器,通过词法,语义分析,结合同义词和停止词,将商品按照相关度降序排序返回。

这里写图片描述

图3-5搜索框展示

搜索建议(Suggestion)

搜索建议功能可以帮助用户在输入某个长词的时候,快速给用户一些建议。比如英文的Refrigerator,如果让用户输入,会很麻烦,尤其是使用手机,平板等没有键盘,屏幕又小的设备时,搜索建议会有很好的用户体验。 Hybris已经封装了Solr Suggestion的API。 调用Hybris的getAutocompleteSuggestions(String input)方法,即可返回建议列表。

这里写图片描述

图3-6自动建议功能

拼写检查(Spell-check)

拼写检查是搜索后返回给用户建议的一种。如果用户输入的词拼写有误,或者没有和这个关键词对应的这一类的商品,Solr提供了根据这个词去给出用户建议关键词的功能。比如搜索“washex”,Solr会给出建议“washer”。 搜索完成后,如果没有结果,可以点击建议,再次搜索。Solr 的search API是默认带有拼写检查功能的,可以根据业务需求,将检查后的建议显示给用户。

这里写图片描述

图3-7 拼写检查

相似匹配(Synonyms)

相似匹配是指搜索包含此关键字的商品的同时,搜索包含此关键字同义词的商品。比如输入“freestanding”,那么除了对关键字“freestanding”进行检索,还可以对同义词“Range”进行检索。

这里写图片描述

图3-8 搜索关键字“freestanding”可以搜索到对应同义词“Range”的商品

Solr可以配置一系列的同义词,Hybris已经把同义词封装成了对象SolrSynonymConfig。同义词是由当前的业务决定的,可以通过impex来添加同义词。

这里写图片描述

图3-9 设置同义词

停止词(Stop words)

停止词的使用,可以使搜索引擎忽略一些匹配程度很高但是没有实际意义的词。比如英文的“a”“an”“but”“the”“which”。这些词在很多商品的名称或者描述信息里面都有,但没有实际意义。忽略这些词,可以提高搜索精度。Solr将停止词封装成一个对象SolrStopWord, 可以通过impex添加停止词。

这里写图片描述

图3-10 设置停止词

提升商品某些属性的匹配权重

Solr 在查询时,给商品的不同属性设置不同的权重,可以提高查询的精确性。比如商品名的匹配权重大于商品描述的匹配权重。Hybris提供了一个可以通过Spring配置的bean,可以设置要查询的属性以及这个属性对应的权重。通过复写,可以添加,修改默认的配置。

这里写图片描述

图3-11 复写查询时属性的权重

商品编号大写问题

Solr在搜索的时候,会将用户输入的关键字英文转换成小写,所有的英文都是按照小写来进行查询的。如果商品的编号是大写的字母的话,会在Solr中按照大写的字符串存储。如果用户输入A1B2C3进行查询,那么转化后会变成a1b2c3。所以搜索不出来对应的商品。
简单的解决办法是在Solr存储的Document里面加上一个新的属性,来存储一个小写的商品编号。然后修改商品搜索时候的查询语句,去查询这个新的属性,那么就会找到对应的商品。

归类(Result Grouping)VS合并(Field Collapsing)

很多搜索引擎是通过Field Collapsing 来进行Document合并的,在Solr的早期版本也使用这种方式。后来Solr推出了Result Grouping这种新的方式来合并Document. 虽然Solr现在还支持Field Collapsing的语法, 但这种方式有一定的局限性,比如合并Document后分组(Facet)统计的结果有时候是不正确的。所以建议通过使用Result Grouping 这种方式来进行返回结果归类。

关于搜索服务的进一步思考

当前的搜索方案并不支持个性化搜索,也就是说两个人输入相同的关键字,搜索到的结果是一样的,并没有结合用户的基本信息和购买记录,推荐出最适合当前用户的商品。想要进一步提升搜索的用户体验,应该在搜索中加入基于用户基本信息和购买记录的的模块,进一步过滤排序商品,从而做到个性化搜索。

总结

Hybris平台对Solr进行了一定的封装,减小了技术层面上使用Solr的复杂性。但这种封装也往往屏蔽了Solr的实现细节,让开发人员不能对Solr的底层工作方式有深刻的理解,不利于结合自身业务进行搜索方案设计。笔者建议开发人员对Solr的底层原理和核心功能进行一定的了解,然后结合自身电商行业的业务特点,充分利用Solr的强大功能,才能搭建一个更加友好的搜索功能。

作者:张彬, 现就职于奥博杰天软件有限公司,担任多个电子商务项目的解决方案架构师。曾担任Tibco 中国研发中心西安办公室BW Plugin 项目组负责人,负责Tibco 消息中间件平台BusinessWorks 6的插件项目设计开发和团队管理工作。关注电商平台发展,人工智能和微服务架构。

相关阅读

猜你喜欢

转载自blog.csdn.net/dev_csdn/article/details/80169381
今日推荐