洞察如何利用第三方app跳转到微信小程序提升企业运营效率
563
2022-11-26
Redis进行职位搜索
本文可作为redis in action第七章的读书笔记
需求背景
job1:skill1,skill2,skill4
job2:skill3,skill2
而每一个应聘者,都有若干个技能
给定一个应聘者,从库里筛选出他能胜任(职位要求的仅能这个人必须都具备,当然他有更多的职位并没有要求的技能也是OK的)的职位
方案一
这也是最符合我们第一思维的逻辑
有一个set域 job:jobid
里面存放了这个职位需要的技能
在检查某个人是否能胜任某个职位的时候
用job:jobid与它本人的技能求差集
如果差集的size等于0说明职位要求的技能,这个人都具备,他可以胜任这个工作
如果差集的size大于0说明职位要求的技能,这个人并不都具备,他不能胜任这个工作
public void addJob(Jedis conn, String jobId, String... requiredSkills) { conn.sadd("job:" + jobId, requiredSkills); } @SuppressWarnings("unchecked") public boolean isQualified(Jedis conn, String jobId, String... candidateSkills) { String temp = UUID.randomUUID().toString(); Transaction trans = conn.multi(); for(String skill : candidateSkills) { trans.sadd(temp, skill); } trans.expire(temp, 5); trans.sdiff("job:" + jobId, temp); List
测试代码:
public class Chapter07Test { static Jedis conn = null; static Chapter07 c=null; @BeforeClass public static void initConn(){ System.out.println("test before"); conn = new Jedis("10.150.0.80"); conn.auth("dlf123123"); c=new Chapter07(); } @Test public void testIsQualifiedForJob() { System.out.println("\n----- testIsQualifiedForJob -----"); c.addJob(conn, "test", "q1", "q2", "q3"); //返回true System.out.println(c.isQualified(conn, "test", "q1", "q3", "q2","q4")); //返回false System.out.println(c.isQualified(conn, "test", "q1", "q2")); }}
OK,上面的代码能正常运行 那么有问题么?
如果库里有10000个职位,那我就得判断10000次
这就是问题
方案二
还有第二种方式
假如有10000个职位,每个职位都有若干个所需技能
我先算出某个人对于这10000个职位里,每个职位都具备几个技能--这个我们称为set-a
然后我还得计算出,每个职位都需要几个技能--这个我们称为set-b
我用setb与seta相减,结果仍然是一个zset集合,member是职位,score等于0的话就说明这个人是能胜任这个工作的#
我们先设计下面几个域
idx:skill:sillId--set集合
这里面列出了,需要这个技能的所有职位信息
idx:jobs:req---zset集合
member是职位 score是这个职位需要的技能的数量
首先将职位与技能添加到库里
public void indexJob(Jedis conn, String jobId, String... skills) { Transaction trans = conn.multi(); Set
好了,我们现在先不看代码了,先说说我们得了解的redis的几个命令
Zunionstore 命令
redis 127.0.0.1:6379> ZRANGE programmer 0 -1 WITHSCORES
1) "peter"
2) "2000"
3) "jack"
4) "3500"
5) "tom"
6) "5000"
redis 127.0.0.1:6379> ZRANGE manager 0 -1 WITHSCORES
1) "herry"
2) "2000"
3) "mary"
4) "3500"
5) "bob"
6) "4000"
# 一共有2个待处理集合分别是programmer和manager
# 给他们的工资分别乘以1和3 我艹 为啥?
# 最后那两个新的工资单 相加
# 结果放到salary集合中
# 公司决定加薪。。。除了程序员。。。
redis 127.0.0.1:6379> ZUNIONSTORE salary 2 programmer manager WEIGHTS 1 3
(integer) 6
redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES
1) "peter"
2) "2000"
3) "jack"
4) "3500"
5) "tom"
6) "5000"
7) "herry"
8) "6000"
9) "mary"
10) "10500"
11) "bob"
12) "12000"
另外对于Zunionstore命令来说,如果待操作的集合并不是有序集合(也就是说没有score域),那么系统就默认认为它的score是1
更详细的见:
如果后台工程师这个职位本身既在c++这个技能要求里,也在db这个技能要求里
最后得出的数据域里后台工程师这个member对应的score就是2
那么下一个问题
我用setb与seta相减,结果仍然是一个zset集合,member是职位,score等于0的话就说明这个人是能胜任这个工作的#
怎么办?WEIGHTS设为-1不就OK了?
上面那个命令是求并集呀?
去看这个命令:ZINTERSTORE
Set
再看看测试代码:
@Test public void testIndexAndFindJobs() { System.out.println("\n----- testIndexAndFindJobs -----"); c.indexJob(conn, "test1", "q1", "q2", "q3"); c.indexJob(conn, "test2", "q1", "q3", "q4"); c.indexJob(conn, "test3", "q1", "q3", "q5"); // System.out.println(c.findJobs(conn, "q1").size()); Iterator
测试结果:
test before ----- testIndexAndFindJobs ----- method: zunionstore jobscores: zrange idx:51926856-67fd-42ba-8620-fa90cae4f4d8 0 -1 withscores method: zinterstore jobscores: zrange idx:b6df8812-f725-46fd-a121-a08c75248d5a 0 -1 withscores test3 abc method: zunionstore jobscores: zrange idx:784ce6b6-5218-4e4d-ac53-b235cf317374 0 -1 withscores method: zinterstore jobscores: zrange idx:990004c6-2c9e-4c26-95b9-248dbf2a5864 0 -1 withscoresabc
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~