合并和求和redis有序集

时间:2012-05-29 08:15:35

标签: python redis

由于使用python dict处理大量数据的性能不佳,我设法迁移到redis。所以我有以下内容:

"doc1" =>  ('989', 4.0), ('99', 4.0), ('990', 4.0), ('991', 4.0), ('992', 4.0), ('993', 4.0), ('994', 4.0), ('995', 4.0), ('996', 4.0), ('997', 4.0), ('998', 4.0), ('999', 4.0)

"doc2" =>  ('4', 4.0), ('21', 4.0), ('55', 4.0), ('991', 4.0), ('992', 4.0), ('993', 4.0), ('994', 4.0), ('995', 4.0), ('996', 4.0)

"result" => ('991', 8.0), ('992', 8.0), ('993', 8.0), ('994', 8.0), ('995', 8.0), ('996', 8.0), ('99', 4.0),('4', 4.0), ('21', 4.0), ('55', 4.0)

正如你所看到的,我想通过使用python将两个redis列表组合成一个,如果doc2中存在doc2中的元素和它们的值相加,如果doc1中的元素不存在于doc2将元素添加到结果中。我之前使用dict的实现是:

result_array = {k: [db_array.get(k, result_array.get(k))[0],db_array.get(k, dv)[1] + result_array.get(k, dv)[1]] for k in set(db_array) | set(result_array)}

how to keep the structure of the dictionary

正如您所看到的,此解决方案适用于:

{'991': [4.0, 's.text'], '21': [4.0, 't.text'], '990': [4.0, 'b.text']}

但redis不支持列表中的列表,因此我必须找到不同的解决方案。

1 个答案:

答案 0 :(得分:2)

如果值是唯一的,您可以使用redis sorted set

zadd doc1 4.0 989
zadd doc1 4.0 991

zadd doc2 4.0 21
zadd doc2 4.0 991

zinterstore result 2 doc1 doc2
zrange result 0 -1 withscores
1) "991"
2) "8"

这将为您提供集合(两个集合中存在的元素)的交集,其中得分是每个集合中元素得分的总和。

要获取doc1但不是doc2中存在的元素比较复杂,因为redis中没有zdiff。根据您的数据(以及两组中存在的元素的分数),您可以这样做(假设所有分数(您称之为“值”)是正数,并且两个集合中相互元素的分数相同): / p>

zunionstore only_in_doc1 2 doc1 doc2 weights 1 -1
zremrangebyscore only_in_doc1 -inf 0
zrange only_in_doc1 0 -1 withscores
1) "989"
2) "4"