有货搜索智能提示设计与实现_zhangfeng.md
6.63 KB
原始需要说明
搜索结果太少
判断搜索结果小于10条,搜索词有推荐词的情况下。顶部显示搜索词的推荐词 ,最多显示5个。
搜索无结果
判断无搜索结果,搜索词有推荐词的情况下。考虑把搜索结果多的或第一个分词设为主推荐词,商品列表页显示推荐词的搜索结果。这个场景下不考虑搜索结果少于20个的处理。商品列表顶部显示主推荐词以外的其他推荐词,最多显示5个,排序不限。推荐用户选择,点击推荐词跳转到该分词的搜索结果页。
搜索实现解析
对于搜索来说,核心是在搜索无结果或结果太少时返回可以搜索出结果的推荐词。对于搜索无结果或者结果太少主要有两种可能:搜索输入条件太多,比如【Vans Stussy 卫衣 鞋子】,没有匹配所有关键词的商品;另外一种可能是用户搜索的关键词有货没有相关的商品,比如【迪奥】。
下面针对以上两种场景分别讨论推荐方案。
搜索输入条件太多的情况
对于这种情况的思路就是拆分关键词,然后返回每个关键词或关键词相关的推荐词。
比如对于【Vans Stussy 卫衣 鞋子】,拆分为四个关键词,然后到suggest索引中匹配。这样处理有两个好处:一个是推荐词的数量很容易得到;另外一个是可以获得“品牌 + 品类”这样的组合推荐词。 当然也有一个问题就是依赖于suggest索引的数据,一些好的推荐词可能不一定包含,这个后续需要考虑优化。
搜索输入为本网不存在的关键词
对于这种情况,最初的思路是想通过word2vec(见说明文章)训练词向量,然后找到用户输入关键字相关的词,再根据这些词到suggest中进行匹配。但是通过训练搜狗120w新闻+有货逛9w文章+有货社区2w文章后发现效果并不好,分析的原因还是相关的语料太少,获取的词向量效果并不好。
基于此,考虑的是一个关键词和有货的关键词的关联关系,考虑到一个采用百度百科爬虫来实现匹配的方案,目前来看效果还不错,具体实现方案见下一小结分析。
基于百度百科爬虫实现的关键词匹配方案
整体方案
- 全量爬虫:从网上获取一份百度百科的分类列表,包括关键词及其链接;初步筛选出与本网相关的关键词,进行初始化归档;环境上线后通过restful接口触发全量URL爬虫,爬虫爬取的内容存放到知识库;
- 增量爬虫:商品搜索系统在执行搜索后判断搜索的数量是否小于10个,如果是的话将该搜索的关键词存放到redis的ZSet中;一个定时任务负责每天从redis的ZSet中获取前1000个搜索关键词,判断有有效关键词后调用爬虫系统爬取内容存放到知识库中;
- 关键词提取:从商品库中提取有货关键词(包括品牌、品类、风格和ParameterMake),并调用ES进行分词(可能对应多个);对百科知识库中的每条关键词的内容进行分词,对于一个有货关键词,如果其分词都在内容分词中,则认为该关键词与有货关键词存在关联关系;如果一个关键词匹配到多个有货关键词,则根据出现的次数排序,取前五个,另外为了保证效果,返回的时候总是尽可能让第一个有货关键词为品类关键词;关键词提取后将它们的映射关系保存到数据库存储;
- 索引构造器:根据上述获取的映射关系建立Elasticsearch索引,给商品搜索系统使用;
- 返回推荐词:根据用户的输入到Elasticsearch索引中进行模糊匹配,返回相关性最高的关键词的有货关键词列表。
实现细节说明
- Redis的ZSet中保存的key为搜索关键词,对应的value为搜索的次数,这样每天处理的就是搜索最多的搜索关键词;
- 增量爬虫的定时任务是在每天凌晨00:30:00执行的,它处理的是前一天搜索最多的搜索关键词;
- 增量爬虫在处理的时候,会对搜索关键词做一些处理,包括关键词合法性检查(都是数字的、长度为1的或者分词后Term太多的就是非法的)、去重处理(百科知识库里面已经有了就不会再去爬了)和黑名单管理(爬取两次失败的就存入黑名单,后续就不会再去爬了);
- 关键词提取的定时任务是在每天凌晨01:40:00执行的,它负责将百科知识库的内容进行转换,如果之前已经进行转换过,当天就不会再处理了;
- 关键词提取时对内容分词返回的是Term及其数量的映射,这样就可以统计出这个内容包含的有货关键词的大致次数,从而得到排序结果;
- 另外对内容分词的时候还会去掉一些没有意义的Term,比如数字、非法字符和自定义的黑名单Term,提升提取效果;
后续计划
- 对于搜索输入条件太多的情况,考虑基于suggest对关键词进行分类,比如标注为品牌、品类、风格等,然后根据不同的分类组合成关键词,这样可能与用户的目标更接近一点;
- 目前是直接返回有货关键词,但是这些关键词是否关联到商品没有保证,后续需要考虑在索引构造器前进行计算和处理(增加这一步骤还需要考虑不同来源的数量处理);
- 目前关键词提取过一次之后就不再进行处理了,如果有货关键词减少了一部分,那原来的关键词映射就需要更新,这个后续需要改进;
- 目前suggest和conversion是两个索引,在获取推荐词的时候可能需要调用两次ES查询,后续考虑合并以及基于suggest获取数量;
- 目前的爬虫调用了大量的Elasticsearch分词,后续考虑在进程内实现分词,减少网络开销;
- 目前有货关键词的范围大约是3000多个,一些搜索常用的词可能不在里面,后续考虑扩展;
- 目前爬虫的是百度百科的内容,可能部分内容不一定有,可以考虑通过下载维基百科语料或者调用百度搜索来获取更多内容来进行关键词提取。