【Redis】有序集合的交集与并集
Redis支持多種類型的數據結構,最簡單的字符串(strings),適合存儲對象的哈希(hash),簡單的字符串列表(list),無序集合(set),有序集合(sorted set),以及用于做基數統計的HyperLogLog,其中使用頻率相對較高的便是集合。
無論是無序集合set,還是有序集合zset,集合內的元素都具有唯一性,如果插入相同的元素,都將被忽略。有時候通過業務邏輯直接存儲的集合,并不能滿足所有的業務需求。比如博客園可以按分類存儲一個set,元素為文章id:
sadd article:type:typeid articleid
sadd?article:type:1?"2" sadd?article:type:1?"3" sadd?article:type:1?"4"按文章的點贊與踩計算出文章分數的有序集合,元素為文章id
zadd article:score score articleid
zadd?article:score?10?"2" zadd?article:score?20?"3" zadd?article:score?2?"4" zadd?article:score?1?"5" zadd?article:score?5?"6"但是如果我們需要在分類下的文章按照分數重新進行排序,怎么辦?既然是集合,我們能想到操作就是,取交集,并集,差集。
1.zinterstore-交集
取這倆集合的交集,就可以完成上面的需求。
zinterstore 可以計算多個有序集合的交集(無序集合的score為0),并生成新的有序集合。
ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight] [SUM|MIN|MAX]
numkey:操作的集合數
weights:是一個可選參數,乘法因子
aggregate:聚合,默認是求和SUM
如果destination新key存在,就被覆蓋。
zinterstore?article:score:1?2?article:type:1?article:score?aggregate?max計算上面兩個集合的交集,以取最大值的方式聚合。
然后就可以通過zrevrange命令按分數從大到小:
zrevrange?article:score:1?0?-12.zunionstore-并集
上面在交集中沒有用到乘法因子,我們將在并集中介紹:乘法因子用于所有的元素的score值在傳遞給聚合函數之前都要先乘以這個因子,說白了,先weights后aggregate。我們就用官方示例說明:
redis>?ZADD?zset1?1?"one" (integer)?1 redis>?ZADD?zset1?2?"two" (integer)?1 redis>?ZADD?zset2?1?"one" (integer)?1 redis>?ZADD?zset2?2?"two" (integer)?1 redis>?ZADD?zset2?3?"three" (integer)?1 redis>?ZUNIONSTORE?out?2?zset1?zset2?WEIGHTS?2?3 (integer)?3 redis>?ZRANGE?out?0?-1?WITHSCORES 1)?"one" 2)?"5" 3)?"three" 4)?"9" 5)?"two" 6)?"10" redis>?按交集操作,key為out的元素只會有one two,但是如果取并集,元素就會有one two three ,默認聚合函數為SUM
所以最終元素:
one
1x2=2
1x3=3
SUM(2+3)=5
two
2x2=4
2x3=6
SUM(4+6)=10
two
0x2=2
3x3=9
SUM(0+9)=9
3.總結
無論是取交集還是并集
以元素為基準做并集與交集操作
score值先與weights乘法因子計算,如果有指定乘法因子的
執行聚合函數,aggregate(),默認SUM,還有MIN MAX
ps:集合操作是要花費時間的,實際操作時,生成的集合key應該設置過期時間,短時間查詢,應該不做交集或并集操作,過期后,才重新做計算。
總結
以上是生活随笔為你收集整理的【Redis】有序集合的交集与并集的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分布式数据库一定会替代Oracle吗?
- 下一篇: c# 通过内存映射实现文件共享内存