原始需要说明
搜索结果太少
判断搜索结果小于20条,搜索词有推荐词的情况下。顶部显示搜索词的推荐词 ,最多显示3个。
搜索无结果
判断无搜索结果,搜索词有推荐词的情况下。考虑把搜索结果多的或第一个分词设为主推荐词,商品列表页显示推荐词的搜索结果。这个场景下不考虑搜索结果少于20个的处理。商品列表顶部显示主推荐词以外的其他推荐词,最多显示3个,排序不限。推荐用户选择,点击推荐词跳转到该分词的搜索结果页。
搜索实现解析
对于搜索来说,核心是在搜索无结果或结果太少时返回可以搜索出结果的提示词。 对于搜索无结果或者结果太少主要有三种可能:
- 搜索输入条件太多,比如【Vans Stussy 卫衣 鞋子】,没有匹配所有关键词的商品;
- 还有一种就是本站有少量商品或过滤后商品数据不多,导致需要推荐提示词,比如【科比】;
- 另外一种可能是用户搜索的关键词有货没有相关的商品,比如【迪奥】;
下面针对以上三种场景分别讨论推荐方案。
搜索输入条件太多的情况
对于这种情况的思路就是拆分关键词,然后返回每个关键词或关键词相关的推荐词。
比如对于【Vans Stussy 卫衣 鞋子】,拆分为四个关键词,然后到suggest索引中匹配。这样处理有两个好处:一个是推荐词的数量很容易得到;另外一个是可以获得“品牌 + 品类”这样的组合推荐词。 当然也有一个问题就是依赖于suggest索引的数据,一些好的推荐词可能不一定包含,这个后续需要考虑优化。
搜索结果太少的情况
对于这种情况的思路就是根据已经匹配到的商品,聚合出品牌、品类、风格等提示词返回。
搜索输入为本网不存在的关键词
对于这种情况,最初的思路是想通过word2vec(见说明文章)训练词向量,然后找到用户输入关键字相关的词,再根据这些词到suggest中进行匹配。但是通过训练搜狗120w新闻+有货逛9w文章+有货社区2w文章后发现效果并不好,分析的原因还是相关的语料太少,获取的词向量效果并不好。
基于此,考虑的是一个关键词和有货的关键词的关联关系,考虑到一个采用百度百科爬虫来实现匹配的方案,目前来看效果还不错,具体实现方案见下一小结分析。
基于百度百科爬虫实现的关键词匹配方案
整体方案
- 全量爬虫:从网上获取一份百度百科的分类列表,包括关键词及其链接;初步筛选出与本网相关的关键词,进行初始化归档;环境上线后通过restful接口触发全量URL爬虫,爬虫爬取的内容存放到知识库;
- 增量爬虫:商品搜索系统在执行搜索后判断搜索的数量是否小于20个,如果是的话将该搜索的关键词存放到redis的ZSet中;一个定时任务负责每天从redis的ZSet中获取前100个搜索关键词,判断有有效关键词后调用爬虫系统爬取内容存放到知识库中;
- 关键词提取:从suggest_word_def表获取有货关键词(包括品牌、品类、风格和ParameterMake),并调用ES进行分词(可能对应多个);对百科知识库中的每条关键词的内容进行分词,对于一个有货关键词,如果其分词都在内容分词中,则认为该关键词与有货关键词存在关联关系;如果一个关键词匹配到多个有货关键词,则根据出现的次数排序,取前10个;关键词提取后将它们的映射关系保存到数据库存储;
- 索引构造器:根据上述获取的映射关系建立Elasticsearch索引,给商品搜索系统使用;
- 返回推荐词:根据用户的输入到Elasticsearch索引中进行模糊匹配,返回相关性最高的关键词的有货关键词列表。
实现细节说明
- Redis的ZSet中保存的key为搜索关键词,对应的value为搜索的次数,这样每天处理的就是搜索最多的搜索关键词;
- 增量爬虫的定时任务是在每天凌晨00:30:00执行的,它处理的是前一天搜索最多的搜索关键词;
- 增量爬虫在处理的时候,会对搜索关键词做一些处理,包括关键词合法性检查(都是数字的、长度为1的或者分词后Term太多的就是非法的)、去重处理(百科知识库里面已经有了就不会再去爬了)和黑名单管理(爬取两次失败的就存入黑名单,后续就不会再去爬了);
- 关键词提取的定时任务是在每天凌晨05:15:00执行的,它负责将百科知识库的内容进行转换;
- 关键词提取时对内容分词返回的是Term及其数量的映射,这样就可以统计出这个内容包含的有货关键词的大致次数,从而得到排序结果;
- 另外对内容分词的时候还会去掉一些没有意义的Term,比如数字、非法字符和自定义的黑名单Term,提升提取效果;
有用的restful接口
-
爬归档的百度百科URL内容 保存至spider_content表
-
将爬虫获取的内容转换为有货关键字 保存至suggest_conversion表
http://192.168.102.224:8088/search-consumer/spider/convertor
-
触发昨天搜索中出现的无结果或小于10条的关键字爬虫 保存内容至spider_content表
http://192.168.102.224:8088/search-consumer/spider/crawerEmptyKeywords
-
单个关键词手工触发
触发爬虫 http://192.168.102.224:8088/search-consumer/spider/single/crawle?keyword=%E5%90%B4%E4%BA%A6%E5%87%A1
触发conversion增量添加 http://192.168.102.224:8088/search-consumer/spider/single/updateES?keyword=%E5%90%B4%E4%BA%A6%E5%87%A1
或者同时执行以上三个步骤 http://192.168.102.224:8088/search-consumer/spider/single/increment?keyword=%E5%90%B4%E4%BA%A6%E5%87%A1
-
重建conversion索引
http://192.168.102.224:8088/search-consumer/index/rebuild/conversion
-
索引增加needSuggestion=Y返回搜索提示
-
查看最近两天无结果或结果少的关键词
http://192.168.102.224:8080/yohosearch/tools/emptyResultKeywords http://192.168.102.224:8080/yohosearch/tools/lessKeyWords
-
爬虫效果说明
http://192.168.102.224:8088/search-consumer/spider/explain?keyword=%E6%B5%AA%E7%90%B4
后续计划
- 目前suggest和conversion是两个索引,在获取推荐词的时候可能需要调用两次ES查询,后续考虑合并以及基于suggest获取数量;
- 目前的爬虫调用了大量的Elasticsearch分词,后续考虑在进程内实现分词,减少网络开销;
- 目前爬虫的是百度百科的内容,可能部分内容不一定有,可以考虑通过调用百度搜索或爬取淘宝的数据来获取更多内容来进行关键词提取。