文档章节

一个热词推荐的简单实现

翟志军
 翟志军
发布于 2017/01/06 06:55
字数 1438
阅读 2971
收藏 143
点赞 3
评论 3

为什么想做这个东西

一直好奇像亚马逊这类网站的搜索是如何做到推荐的,最近刚好看到一篇文章:Redis 与搜索热词推荐,然而只写了思路。所以,就是想自己实现一个。

先上个效果图,再聊:

xxx

P.S. 按四年前,要写这样的前端效果,对于我这个后台开发,还是挺困难的。而现在,简单的学了下Vue.js,再加上同事的小小指点,就搞定了。😂

热词推荐的本质

假如你预先就知道了用户输入:s、sz、shen、深这些字时,就是想搜“深圳”,那是不是说,我们只要提前将这些字放到一个Map结构中,将用户的输入想像出一个key,value就是“深圳”。

说到底,热词推荐的本质就是一个大大的Map。难点就在于如何更新这个Map,以至于让用户觉得“智能”,或觉得我们在给他们做“推荐”。

这个Map,常常被人称为“索引”。其实使用“索引” 这个名词也更准确一些。Map中的Key是不能重复的。但是我们数据结构是要求可重复的,为什么呢?因为,在系统中,s、sh、shen、深等等这些都是key,而它们对应的value,可能相同,又可能不同。举个例子:

hotword:0>zrevrange s 0 10
1) 鼠蛟
2) 鼠场乡
3) 鳝鱼
4) 鳝溪校区
5) 鳝溪农场
6) 鳝溪
7) 骚子营社区
8) 骚子营
9) 驷马镇
10) 驷马桥街道
11) 驷马桥
hotword:0>zrevrange sh 0 10
1) 鼠蛟
2) 鼠场乡
3) 鳝鱼
4) 鳝溪校区
5) 鳝溪农场
6) 鳝溪
7) 首院胡同
8) 首阳镇
9) 首阳山镇
10) 首阳山
11) 首钢试验厂

仔细看到其中的不同了吗?同时,这里还有一个问题,那就是当用户输入s时,出现了10个value,我们如何给这些value如何排序呢?

为了与排序模型解耦,我们为每个value都给出一个分数score。score越大,越排前面。最终索引结构就变成了这样子:

vv

P.S. 这些score之所以都为0,是因为数据问题。

总的来说,关于热词推荐,我们需要解决以下问题:

  • 如何存储索引的数据?

  • 如何构建索引?也就是一开始时,我们怎么知道用户输入“s” 就是要搜“深圳”呢?

  • 如何根据用户的反馈行为来更新索引?当用户输入 “s” 出现了“1 沙河”和“2 深圳”,用户选择了“深圳”,那么当其他用户输入“s”时,我们是不是应该将“深圳”这个词放到前面呢?

基于Solr实现的弊端

美团在几年前也写了一篇文章来介绍自己的热词推荐:搜索引擎关键字智能提示的一种实现。然而这种实现,个人觉得有个设计非常不好。因为Solr在整个系统中,即做了“存储索引”的角色,又做了“构建索引”的角色。违反了职责单一原则。因为当我们想改变构建索引的算法时,同时会影响到“存储索引”的逻辑。

以下是他们的实现逻辑截图:

另一种基于Redis的实现

我目前只写了一个简单实现,而且还没有实现“根据用户反馈来更新索引”的功能。这个功能可实现得很简单,也可以实现得很复杂。本文不讨论。

同时,生产环境会更复杂一些。比如要实现高可用。我个人能力有限,还没有能实现。但是思路是有的:所有出现单点的地方都要做成分布式的,比如Redis就做成Redis Cluster。

以下是架构图:

图中,InitWorker负责将我准备好的全国地名大全的数据,构建成索引,然后写到Redis中。用户则可以通过基于Openresty写的APP去查询Redis中的数据。

使用本系统的方法:

P.S. 本系统使用Ansible做自动化部署,所以,请提前安装好Ansible。

  1. git clone https://github.com/zacker330/hot-word-recommend.git
  2. 准备两个Ubuntu 16的机器,如果你懂Vagrant的话,直接使用我的Vagrantfile就好了
  3. 进入到项目中,执行ansible-playbook ./ansible/playbook.yml -i ./ansible/inventory -u vagrant -k 来自动化部署所有组件。如果使用Vagrant来搭建的环境,密码是 vagrant,以下同,将不在重述。
  4. 打包我们的InitWorker项目:mvn assembly:assembly
  5. 部署InitWorker: ansible-playbook ./ansible/deploy-worker.yml -i ./ansible/inventory -u vagrant -k
  6. 打开链接测试:http://192.168.10.11/index.lsp 。IP换成你自己部署的机器的IP。

具体代码,自己看了。为方便阅读,我觉得有必要注释一下项目结构:

├── README.md
├── Vagrantfile
├── ansible
│   ├── deploy-front-app.yml // 单独部署 前端app
│   ├── deploy-local.yml //本地开发使用
│   ├── deploy-worker.yml // 执行worker,写索引到redis中
│   ├── inventory
│   ├── playbook.yml // 安装所有必要的组件
│   ├── roles
│   │   ├── common
│   │   ├── front-app // 安装前端APP
│   │   ├── jdk8 // 安装Jdk8
│   │   ├── openresty // 安装Openresty
│   │   └── redis // 安装redis的脚本
│   └── vars
│       └── base-env.yml  // 配置变量存放文件
├── autocomplete-worker
│   ├── pom.xml
│   ├── src
│   │   ├── main
│   │   │   ├── java
│   │   │   │   └── codes
│   │   │   │       └── showme
│   │   │   │           └── autocomplete
│   │   │   │               ├── InitWorker.java    
│   │   │   │               └── common
│   │   │   └── resources
│   │   │       └── env.properties
│   │   └── test
│   └── target
├── doc // 文档需要用到的一些文件
└── files
    └── places.txt.zip  //全国地名数据

小结

热词推荐的“智能”所在处就在于索引的构建算法。简单一点的做法就是每当用户点击某搜索结果时,我们就给这个索引条目加权1。感兴趣的同学可以实现来玩玩。

以上内容均为个人看法,如果有不对的地方,还请斧正,谢谢了。

项目地址为:https://github.com/zacker330/hot-word-recommend

转自:https://showme.codes/2016-12-31/hot-word-recommend-demo/

© 著作权归作者所有

共有 人打赏支持
翟志军

翟志军

粉丝 339
博文 76
码字总数 79851
作品 2
深圳
程序员
加载中

评论(3)

yongk
yongk
应该用es这种的做热词,index就是为了search,它的单一职责就是搜索,但实现搜索你先要建索引。
MGL_ONE
MGL_ONE
solr弊端、、、这个、、、
一只小桃子
一只小桃子
难道不是solr和elsearch 自带的suggestion功能
Redis 与搜索热词推荐

本文作者:伯乐在线 -v7 。未经作者许可,禁止转载! 欢迎加入伯乐在线专栏作者。 摘要 本文解决一个非常普通的需求:在用户输入搜索关键词的过程中,系统给出搜索的推荐关键词。 实现的方式...

伯乐在线
2015/12/09
0
0
和文本分析有关的问题 我是纯小白 中科院ICTCLAS

大家好,我是今年毕业的应届生小白,公司让做一个功能:搜索热词分析。简单说就是有一个类似于天猫那样的电商平台,用户会在上面输入一系列的搜索词,比如:夏季裙子、短裙。我现在要找出用户...

白露姑娘
2016/08/24
54
3
纽约时报的主编竟是一个叫做Blossom的机器人

纽约时报的主编竟是一个叫做Blossom的机器人 《纽约时报》的主编绝对是一个要职,每天的工作是负责超过300篇各式文章当中挑出最火的文章,推荐给各大版面的增长编辑以及社交媒体编辑。 到底哪...

行者武松
03/01
0
0
一种海量社交短文本的热点话题发现方法

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯QQ大数据 发表于云+社区专栏 随着社交网络的发展和积累,内容的产生、传播、消费等已经根深蒂固地融入在人们的生活里。...

腾讯云+社区
07/13
0
0
垂直搜索引擎中的用户行为数据价值解析

垂直搜索引擎是网站/APP里提供的搜索窗口,让用户通过搜索关键词就直达目标内容。上一篇文章中已经做过简单解释,并且从易读性角度阐述了其三个应用阶段。 此篇文章则详细讲述用户在应用垂直...

达观数据
2017/08/10
0
0
iOS开发者React Native学习路线

http://blog.talisk.cn/blog/2016/08/13/RN-Learning-path-for-iOS-developer/ 既然是写给iOS开发者的,那么我默认你已经掌握iOS原生应用开发的基本知识,所以对iOS原生开发的相关内容不做解...

卡奇匠
2016/12/13
18
0
【python数据挖掘课程】十五.Matplotlib调用imshow()函数绘制热图

前面系列文章讲过数据挖掘的各种知识,最近在研究人类时空动力学分析和幂率定律,发现在人类兴趣转移模型中,可以通过热图(斑图)来进行描述的兴趣转移,如下图所示。下一篇文章将简单普及人...

Eastmount
2017/06/20
0
0
关于Android热更新琐碎记录

最近比较闲,就接手了一个比较烫手的山芋,热更新,这个被抄烂的词。 下面是这段事件我在做技术调研的时候收集的方案,和最终选型的记录。 1 ):Andfix(alipay开源出来的一个android热修补方...

hehr_os
2016/11/17
33
0
2017年IT人年终总结,一个都不知道的你这一年就白过了

移动互联时代,每天都会涌现大量新词热词,我们IT圈也不例外,2017年就要过去了,是时候来回顾下这一年都发生了什么 首先来看看2017年互联网的热词与流行语,原来2017年的年轻人们聊天最经常...

uzv80px5v412ne
2017/12/30
0
0
用solr的facet实现聚合标签

Facet,单词意思是侧面,小平面。哈哈,怎么学英文单词了…… 好吧,言归正题,solr的Facet是一个什么东西呢?我个人理解,反映一个搜索词的小平面(或者说某一个分组),起到标签聚合统计的...

lavafree
2013/01/18
0
17

没有更多内容

加载失败,请刷新页面

加载更多

下一页

面试感想(一)

最近跟北京的同事朋友聊天,深深的发现自己的技术已经和主流技术脱轨了,目前公司求稳为主,使用的技术略有些过时,因此萌生出了换工作的念头,正值三伏天,可以说真是顶着一颗偌大的决心去参加面试...

勤奋的蚂蚁
2分钟前
0
0
Kafka设计解析(一)- Kafka背景及架构介绍

原创文章,转载请务必将下面这段话置于文章开头处。(已授权InfoQ中文站发布) 本文转发自技术世界,原文链接 http://www.jasongj.com/2015/03/10/KafkaColumn1 摘要   Kafka是由LinkedI...

mskk
12分钟前
0
0
使用Service Mesh整合您的微服务架构

在微服务架构的世界中,它正在达到这样的程度,即管理系统的复杂性对于利用它带来的好处变得至关重要。 目前,如何实现这些微服务不再是一个问题,因为有很多可用的框架(Spring Boot,Vert....

xiaomin0322
15分钟前
0
0
看看 LinkedList Java 9

终于迎来了 LinkedList 类,实现的接口就有点多了 Serializable, Cloneable, Iterable<E>, Collection<E>, Deque<E>, List<E>, Queue<E>。LinkedList是一个实现了List接口和Deque接口的双端链......

woshixin
34分钟前
0
0
算法 - 冒泡排序 C++

大家好,我是ChungZH。今天我给大家讲一下最基础的排序算法:冒泡排序(BubbleSort)。 冒泡排序算法的原理如下: 比较相邻的元素。如果第一个比第二个大(可以相反),就交换他们两个。 对每...

ChungZH
36分钟前
0
0
jquery ajax request payload和fromData请求方式

请求头的不同 fromData var data = { name : 'yiifaa'};// 提交数据$.ajax('app/', { method:'POST', // 将数据编码为表单模式 contentType:'application/x-ww...

lsy999
39分钟前
0
0
阿里P7架构师,带你点亮程序员蜕变之路

前言: Java是现阶段中国互联网公司中,覆盖度最广的研发语言。 掌握了Java技术体系,不管在成熟的大公司,快速发展的公司,还是创业阶段的公司,都能有立足之地。 有不少朋友问,成为Java架...

Java大蜗牛
40分钟前
1
0
Ecstore 在没有后台管理界面(维护)的情况如何更新表的字段

window 系统: 切换到:app\base 目录下: C:\Users\qimh>d: D:\>cd D:\WWW\huaqh\app\base 执行:D:\WWW\huaqh\app\base>cmd update linux 系统: 1># cd /alidata/www.novoeshop.com/app/......

qimh
45分钟前
0
0
设计模式-策略模式

策略模式 解释 对工厂模式的再次封装,使用参数控制上下文信息(将工厂返回的实例赋值给context field) 不会返回bean实例,只是设置对应的条件 调用context的方法(调用field的方法) 用户只...

郭里奥
47分钟前
0
0
python使用有序字典

python自带的collections包中有很多有用的数据结构可供使用,其中有个叫OrderedDict类,它可以在使用的时候记录元素插入顺序,在遍历使用的时候就可以按照原顺序遍历。 a = {"a":1,"b"...

芝麻糖人
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部