由于使用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不支持列表中的列表,因此我必须找到不同的解决方案。
答案 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"