2017-09-12 36 views
3

我有一些数据要存储在redis中才能够有效地相交。示例数据:相交的redis集是不完整的

key | members 
--------------------------------- 
101 | "a1", "a2", "a3" 
102 | "a2", "a3" 
103 | "a2", "a4" 

因此,这些密钥的交集会给我

SINTER 101 102 103 
1) "a2" 

不过,我有一些问题,当这些数据不完整:

key | members 
--------------------------------- 
101 | "a1", "a2", "a3" 
102 | "a2", "a3" 
103 | "a4", "a5" 

在这种情况下,得到相同的三个键的交集会给我一个空集:

SINTER 101 102 103 
(empty list or set) 

我的目标是获得匹配大多数集合的成员。在redis中有没有办法实现这一点?如果有帮助,我可以改变我的数据集的存储方式。即创建集合的反向版本(成员作为键,作为成员的键)

此外,它可能是有意义的使用比redis更多的其他密钥存储,这可能更适合于此任务?

+0

如果设置的'101'包含了''和'B',设置'102'包含'b'和'c',并且设置'103'包含'c'和'd'? –

回答

2

您可以使用AGGREGATE SUM参数对有序集合进行联合操作。这有点笨重,但它会起作用。基本上将所有元素添加1分,然后通过总结分数来合并。

的结果集将从元素最交点进行排序,以用最少的元素:

127.0.0.1:6379> zadd foo 1 a 
(integer) 1 
127.0.0.1:6379> zadd foo 1 b 
(integer) 1 
127.0.0.1:6379> zadd foo 1 c 
(integer) 1 

127.0.0.1:6379> zadd bar 1 a 
(integer) 1 
127.0.0.1:6379> zadd bar 1 c 
(integer) 1 

127.0.0.1:6379> zadd baz 1 d 
(integer) 1 

# Now let's do the union and store it into "merged" 
127.0.0.1:6379> ZUNIONSTORE merged 3 foo bar baz AGGREGATE SUM 
(integer) 4 

# Merged is now sorted by common points 
127.0.0.1:6379> ZREVRANGE merged 0 -1 WITHSCORES 
1) "c" 
2) "2" 
3) "a" 
4) "2" 
5) "d" 
6) "1" 
7) "b" 
8) "1" 
127.0.0.1:6379> 
+0

谢谢,这个作品很棒! –

+0

@Sævar记住,如果你有很多大牌,表现是可怕的。它需要遍历每个集合中的每个元素。 –

+1

优雅的解决方案!还要注意以下情况:合并集合中所有项目的分数为1。 –