阿里云
发表主题 回复主题
  • 12073阅读
  • 12回复

[使用教程]基于OpenSearch实现商品搜索原型

发帖
337
云币
538
某位同学在使用OpenSearch系统为某大型企业做的demo,供电商需求同学参考。

---------------------------------------------------------------我是分割线------------------------------------------------------------------  

在类似物资采购电商平台建设中,有一块重要的业务要求是可通过关键字搜索的方式对商品信息中不同属性进行搜索,同时可对搜索出的商品列表进行分类的过滤查看(如下图),实现的效果很像淘宝、阿里巴巴的电商平台。



需求分析

  确定了需要实现的搜索效果,接下来是要分析商品在数据中的结构,与搜索相关的几张数据库表主要表结构如下:

上图中红色标记为对应表中的模拟数据,用于说明这几表间的关联关系。最终实现的搜索功能支持对商品中各属性进行关键字搜索,并对搜索出的商品结果列表中商品所包含的属性或规格进行分类查看。


方案设计

     项目开发周期非常紧张,面对这样一个不算简单的搜索需求,首先想到是采用成熟的搜索平台快速满足此搜索功能,然想到是采用阿里云上OpenSearch产品实现一个商品搜索的原型,验证OpenSearch目前提供的功能是否能实现项目的需要。
     整个原型的系统架构如下:

  通过将商品中心中的商品相关数据同步到OpenSearch服务后,通过OpenSearch提供的搜索API进行商品的搜索。


原型实现



创建索引结构

      在确定最后的索引结构前,确实费了一般周折,因为OpenSearch不支持主表与子表 1对多的映射关系,仅支持1:1,也就是说完全按照数据库中表结构创建索引结构是不支持的,会出现无法对商品包含的很多属性和规格值进行搜索。感觉需要放开思维,索引结构的创建是为了最终满足业务上对于搜索的要求,在尽量减少对数据库表结构字段修改的前提下,完全可以在遵循OpenSearch索引结构规则前提下,进行索引结构的创建,完全不必担心会有冗余索引数据的产生。最终,我们采用以下方式创建了索引表结构:
  1. 商品属性表为索引的主表,商品表为辅表的方式,将实际数据库中规格表和属性表的数据均同步到索引的主表商品属性表中;
  2. 因为最终搜索出的结果均是以商品的形态展现,不会出现单独单品的结果。所以采用在规格表中添加商品的id信息,直接建立规格表与商品表间的关联关系,省去单品表在其中的关联映射;
   原型所用的索引结构如下图:



配置数据源

  重点是将属性表和规格表中的数据均同步到索引的主表中,如下图所示:



原型开发

     在了解了OpenSearch的搜索URL语法后,开始原型的开发,在其中主要用到了以下几个关键的语句和函数实现了相应的搜索功能:


对索引字段进行全文检索

      通过将商品表、属性表、规格表、品牌表等索引表中需要搜索的相关字段添加到索引列表“default”中,见下图:

这样就能通过query:’搜索关键字’,对商品进行搜索操作了。


对搜索结果进行去重

      因为我们采用属性表作为索引主表,而一件商品会包含多个不同的属性和规格信息,这样就会出现同一件商品会多次出现在商品的搜索结果中,则需要采用distinct子句对搜索结果进行去重操作,相关代码如下:

     第二行设置kvpairs为duniqfield:product_id,是为了从结果中去重后,结果数量也能正常显示。


获取分类列表

     为了实现在商品结果中将商品包含的所有分类信息都能获取到,需要使用aggregate子句对property进行聚合操作,以获取搜索结果中不同的属性名,代码如下:

    即在搜索结果中同时获取品牌和属性的聚合列表。


价格进行过滤

    业务上还支持按价格区间进行结果的查看,需要采用filter子句,对价格字段进行过滤操作,相关代码如下:



原型效果

   经过几天的学习和调测,最终实现了商品搜索的原型如下:

搜索结果如下:

搜索结果分类过滤结果




总结

      经过几天OpenSearch的使用,个人认为OpenSearch提供了比较完善的搜索服务和API接口,能够基于OpenSearch快速实现业务对于搜索的需求,既能大大提高搜索功能实现的开发效率,同时也避免了搭建复杂搜索引擎平台带来的系统部署和运维的工作量和成本。同时,也感觉OpenSearch在支持一些复杂搜索需求的场景中存在着功能上的不足,不过相信OpenSearch的产品团队会逐步完善增强OpenSearch,弥补这些不足。
     最后感谢在整个原型开发工程中,给予大力支持的OpenSearch各位同学!


[ 此帖被zhengmay在2015-02-13 18:31重新编辑 ]
本帖最近评分记录: 1 条评分 云币 +1
陈昶安 云币 +1 您的无私奉献精神值得我们学习!向您致敬! 2015-03-09
发帖
94
云币
241
只看该作者 沙发  发表于: 2015-03-02

这位同学尝试找到同淘宝商品搜索一样的展现方式,这个改进后的解决方案可以实现类似淘宝的电商平台,很强大!分享给大家哇~~

---------------------------------------------------------------我是分割线------------------------------------------------------------------  

  • 尝试

      我开始继续学习了解OpenSearch相关技术文档,尝试能找出一个能真正实现跟淘宝一样效果的方法。看到OpenSearch提供了API可通过程序直接插入索引文档,而无需配置数据源与索引数据的映射和同步,采用这样的方式,就可以将业务端复杂的数据关联关系与索引数据进行分离,只需在OpenSearch中创建一个简单的索引数据结构,在程序端将业务数据库中复杂的关联关系处理完毕,生成最终的索引文档,通过API直接插入到搜索引擎中。
     经过尝试,很快就实现了通过输入商品相关信息,保存后自动将商品信息写入到OpenSearch中,并且索引实时生效!

  • 真正的解决方案现身

      虽然采用API的方式成功屏蔽了OpenSearch对于索引数据结构的约束,但因为仅支持主表到子表的1:1关联,依然无法支持多次分类过滤,好在关键时候得到了OpenSearch产品团队的支持,提出了将所有商品属性都保存到商品表的一个字段中,该字段中包含了该商品所有的属性信息(属性名、对应属性值),然后将该字段的类型设置为Text_Array(而不是普通的Text类型),这样OpenSearch会自动为该字段创建正排索引(也叫attribute),然后通过对该字段进行aggregate聚合操作,就能获取各属性的聚合信息。因为每一个索引值是即包含属性名,也有属性值的一个值,在获取到聚合结果后,只需做一下简单的排序和合并处理,就能组装成前端界面所需的展现数据。
      实现方法提出后,我迫不及待的在原有原型上开始了验证工作,一个多小时后,最终成功验证了这样的方法能完美的实现商品搜索的要求。

  • 实现说明索引数据表创建

      因为需要将一个商品所有的属性信息保存到一个字段中,采用数据库同步的方式必然带来数据组装、同步、冗余的问题,正好之前测试了以API的方式写入索引数据,正好派上用场,这样在OpenSearch的索引数据表只需非常简单的结构,需要重点注意的是allattributes字段的类型是Text_Array,如下图:


  • 索引文档的写入

      我编写了一个简易的商品信息输入表单,通过“保存”按钮即将用户输入的商品信息直接通过API的方式在搜索引擎中创建索引文档,重点是属性值,我在前端采用“;”(在索引中并不是以“;”为分隔,这里仅作为测试使用)的方式将多个属性名值对做了隔离,每个属性名值对以“_”连接,如“颜色_红色”,及该商品具有属性名为颜色,对应属性值为红色的一个属性,界面如下图:


将商品信息通过API写入搜索引擎的代码如下,重点注意allattributes对应的属性是一个数组对象



  • 多次分类过滤查看支持

      当完成了上述工作后,接下来就是获取到对应的分类信息后进行合并处理工作,具体在这里不做介绍,最终实现的效果如下:




  • 总结

      到此,基于OpenSearch实现如类似淘宝商品搜索的原型工作会告一段落,希望对将来遇到有类似需求的同学提供一些参考和帮助。在此感谢OpenSearch团队的大力支持,相信你们的产品会越来越好。



[ 此帖被rosamond在2015-03-02 15:21重新编辑 ]
级别: 小白
发帖
3
云币
17
只看该作者 板凳  发表于: 2015-03-09
您的无私奉献精神值得我们学习!向您致敬!
级别: 小白
发帖
41
云币
47
只看该作者 地板  发表于: 2015-03-25
Re基于OpenSearch实现商品搜索原型
学习一下。
级别: 新人
发帖
7
云币
9
只看该作者 4楼 发表于: 2015-03-28
Re基于OpenSearch实现商品搜索原型
学习了 感谢分享!
级别: 小白
发帖
10
云币
8
只看该作者 5楼 发表于: 2015-04-27
Re基于OpenSearch实现商品搜索原型
赞!
级别: 新人
发帖
2
云币
2
只看该作者 6楼 发表于: 2016-06-14
Re基于OpenSearch实现商品搜索原型
商品属性一定要用sdk生成的吗
级别: 新人
发帖
2
云币
2
只看该作者 7楼 发表于: 2016-06-14
回 6楼哈哈234的帖子
链接RDS没办法生成吗?
级别: 新人
发帖
1
云币
1
只看该作者 8楼 发表于: 2016-08-16
Re基于OpenSearch实现商品搜索原型
你好,如果数据量比较大的情况,比如我的商品通过DRDS按productID分库到100个RDS,那需要将这100个库映射至opensearch?
级别: 新人
发帖
1
云币
1
只看该作者 9楼 发表于: 06-19
回 1楼rosamond的帖子
你这个方法在最新的版本上怎么实现,类似于淘宝电商,属性的设置。关键是属性的设置要详细点的??????
[ 此帖被asda12在2018-06-19 09:25重新编辑 ]
级别: 新人
发帖
3
云币
3
只看该作者 10楼 发表于: 08-09
Re基于OpenSearch实现商品搜索原型
同问tag String_arraylist的索引设置。 这种场景下opensearch对分库分表读入的性能支持的怎么样...?
级别: 论坛版主
发帖
399
云币
571
只看该作者 11楼 发表于: 08-10
学习了。直接用全文检索是不是很low?

[ 此帖被云上珠玑在2018-09-12 08:56重新编辑 ]
本人是阿里云社区社招版主,并非阿里云官方人员,发帖回答仅提供参考。
级别: 程序猿
发帖
497
云币
745
只看该作者 12楼 发表于: 09-12
这个厉害了。。
 
[ 此帖被服务器云在2018-11-26 21:55重新编辑 ]
发表主题 回复主题
« 返回列表上一主题下一主题

限100 字节
如果您在写长篇帖子又不马上发表,建议存为草稿
 
验证问题: 阿里云官网域名是什么? 正确答案:www.aliyun.com
上一个 下一个