下面由redis教程欄目給大家介紹關(guān)于java基于redis有序集合實(shí)現(xiàn)排行榜,希望對(duì)需要的朋友有所幫助!
前言
排行榜作為互聯(lián)網(wǎng)應(yīng)用中幾乎必不可少的一個(gè)元素,能勾起人類自身對(duì)比的欲望,某寶中的商品銷量排行,店鋪信譽(yù)排行等,實(shí)現(xiàn)排行榜的方式也有很多種,可以使用快速排序算法 實(shí)現(xiàn)comparator接口實(shí)現(xiàn)按某項(xiàng)權(quán)重排序,現(xiàn)在很多公司都在使用redis這個(gè)nosql數(shù)據(jù)庫(kù)實(shí)現(xiàn)排行榜的功能
基于redis實(shí)現(xiàn)排行榜
現(xiàn)在要做的是對(duì)公司進(jìn)行排行,排行的標(biāo)準(zhǔn)是用戶對(duì)公司的搜索次數(shù),做一個(gè)前十公司的排行榜
1.相關(guān)的redis知識(shí)
與排行榜功能實(shí)現(xiàn)相關(guān)的redis數(shù)據(jù)結(jié)構(gòu)是sort set(有序集合)
關(guān)于sort set
我們知道set是一種集合,集合有一個(gè)特點(diǎn)就是無重復(fù)元素,sort set除了無重復(fù)元素外,還有一個(gè)特點(diǎn)就是有序性。
數(shù)據(jù)結(jié)構(gòu)組成:
key:sort set 的唯一標(biāo)識(shí)權(quán)重:也叫分?jǐn)?shù)(score)redis通過權(quán)重為集合中的元素進(jìn)行升序排序(默認(rèn)),權(quán)重可以重復(fù)value:集合元素,元素不可重復(fù)
string(set key),double(權(quán)重),string(value)sort set是通過哈希表實(shí)現(xiàn)的,所以添加,函數(shù),查找的時(shí)間復(fù)雜度都是o(1),每個(gè)集合可以存儲(chǔ)40多億個(gè)元素
基本命令
向集合中添加一個(gè)或多個(gè)元素
zadd "key" score "value" [ score "value"]效果:
myredis:0>zadd test 1 "one""1"myredis:0>zadd test 4 "four" 5 "five""2"獲取集合的元素?cái)?shù)量
zcard "key"效果
myredis:0>zcard test"5"獲取指定元素分?jǐn)?shù)(權(quán)重)
zscore "key" "value"效果
myredis:0>zscore "test" "one""2"指定集合的指定元素增加指定分?jǐn)?shù)
zincrby "key" score "value"效果:
myredis:0>zscore "test" "one""2"myredis:0>zincrby "test" 1 "one""3"myredis:0>zscore "test" "one" "3"獲取指定范圍的元素(默認(rèn)按照分?jǐn)?shù)|權(quán)重的升序排列)
zrange "key" 開始下標(biāo) 結(jié)束下標(biāo)效果
myredis:0>zrange "test" 0 1 1) "two" 2) "one"完成這個(gè)需求大概需要這么多命令,接下來開始實(shí)現(xiàn)我們的這個(gè)需求
2.springboot redis實(shí)現(xiàn)
導(dǎo)入redis依賴
<dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-data-redis</artifactid> </dependency>編寫工具類
//=============================== sort set ================================= / * 添加指定元素到有序集合中 * @param key * @param score * @param value * @return */ public boolean sortsetadd(string key,double score,string value){ try{ return redistemplate.opsforzset().add(key,value,score); }catch (exception e){ e.printstacktrace(); return false; } } / * 有序集合中對(duì)指定成員的分?jǐn)?shù)加上增量 increment * @param key * @param value * @param i * @return */ public double sortsetzincrby(string key,string value,double i){ try { //返回新增元素后的分?jǐn)?shù) return redistemplate.opsforzset().incrementscore(key, value, i); }catch(exception e){ e.printstacktrace(); return -1; } } / * 獲得有序集合指定范圍元素 (從大到小) * @param key * @param start * @param end * @return */ public set sortsetrange(string key,int start,int end){ try { return redistemplate.opsforzset().reverserange(key, start, end); }catch (exception e){ e.printstacktrace(); return null; } }業(yè)務(wù)實(shí)現(xiàn):
因?yàn)榕判邪駥?duì)實(shí)時(shí)性要求比較高,個(gè)人認(rèn)為沒必要進(jìn)行持久化到數(shù)據(jù)庫(kù)
/ * 根據(jù)公司名找到指定公司 * @param companyname * @return */ @override public ajaxresult selectcompanyname(string companyname) { set<object> set = redisutils.sget("company"); for(object i : set){ string json = jsonobject.tojsonstring(i); jsonobject jsonobject = jsonobject.parseobject(json); if(jsonobject.getstring("companyname").equals(companyname)){ //搜索次數(shù) 1 redisutils.sortsetzincrby("companyrank",companyname,1); log.info("直接緩存中返回"); return new ajaxresult().ok(jsonobject); } } log.error("緩存中沒有,查數(shù)據(jù)庫(kù)"); tbcommpanyexample tbcommpanyexample = new tbcommpanyexample(); tbcommpanyexample.createcriteria().andcompanynameequalto(companyname); list<tbcommpany> list = tbcommpanymapper.selectbyexample(tbcommpanyexample); if(list.size() != 0){ //放入緩存中 redisutils.sset("company",list.get(0));