python - 在 Redis 上存储和访问复杂 JSON 对象的最快和最佳方式
问题描述
我一直在使用 ReJSON( json.set
) 在我的 redis 服务器上存储复杂的 JSON。例如:
{'2018-02-01' : {'cid_1':{ 'city_1: {'mid_1: {'user_data : ...},{'merchant_data': ...},{'item_data':...}...}...}...}
一次访问一个键非常快。但是访问数月的数据并添加它需要相当多的时间。
是否有另一种更好的方法来存储/访问这些复杂的 json 结构:
1)因此,如果我只需要user_data
,不必检索所有其他数据,然后过滤掉其余数据,例如:
dict_a = rj.jsonget(self.start_date, rejson.Path.rootPath())
dict_a = dict_a[self.cid][self.city][self.merchant]['User_data']
按时测试后,我发现 99% 的时间都花在了获取和计算数据上。那么基于此,您认为我的代码需要更多优化吗?
def calculate_total(self,T):
delta = self.delta()
for i in range(delta):
try:
dict_a = rj.jsonget(self.start_date, rejson.Path.rootPath())
if T == 1:
dict_a = dict_a[self.cid][self.city][self.merchant]['Merchant_data']
elif T == 2:
dict_a = dict_a[self.cid][self.city][self.merchant]['User_data']
elif T == 3:
dict_a = dict_a[self.cid][self.city][self.merchant]['Item_data']
break
except KeyError:
self.start_date = str((datetime.strptime(self.start_date, '%Y-%m-%d') + timedelta(days=i)).date())
else:
return ('Error 404- No Data found for %s, in %s on %s'%(self.cid,self.city,start_date))
for i in range(delta):
new_date = str((datetime.strptime(self.start_date, '%Y-%m-%d') + timedelta(days=i+1)).date())
try:
dict_b = rj.jsonget(new_date, rejson.Path.rootPath())
if T == 1:
dict_b = dict_b[self.cid][self.city][self.merchant]['Merchant_data']
elif T == 2:
dict_b = dict_b[self.cid][self.city][self.merchant]['User_data']
elif T == 3:
dict_b = dict_b[self.cid][self.city][self.merchant]['Item_data']
else:
dict_b = rj.jsonget(new_date, rejson.Path.rootPath())
dict_a = merge_dict(dict_a,dict_b)
except KeyError:
pass
return (dict_a)
def merge_dict(dictA, dictB):
new_dict = {}
common_keys = set([key for key in dictA if key in dictB] + [key for key in dictB if key in dictA])
for k, v in dictA.items():
#add unique k of dictA
if k not in common_keys:
new_dict[k] = v
else:
#add inner keys if they are not containing other dicts
if type(v) is not dict:
if k in dictB:
new_dict[k] = v + dictB[k]
else:
#recursively merge the inner dicts
new_dict[k] = merge_dict(dictA[k], dictB[k])
#add unique k of dictB
for k, v in dictB.items():
if k not in common_keys:
new_dict[k] = v
return new_dict
解决方案
而不是将这个复杂的json存储在redis中,它需要使用redis数据结构逐个存储。在以这种方式存储时,请记住在检索数据时需要执行的查询。这将带您正确使用不同的 redis 数据结构来最小化查询执行时间。
推荐阅读
- grpc - gRPC Stackdriver 问题
- python - Python Selenium - 获取href值
- java - 春季启动 2. Java 10. JUnit。org.slf4j 包可以从多个模块访问:
, slf4j.api - c++ - 使用cmake,我如何将第三方库链接到我自己的程序(找到项目,从源代码构建,并安装,链接)
- javascript - 从节点js中的数据库中检索图像
- node.js - 如何在nodejs中获取与来自mongodb的问题相对应的特定字段
- angularjs - 未知提供者:$intervalProvider <- $interval <-infiniteScrollDirective
- javascript - 使用 CTRL + END 的量角器
- c# - ASP.Net 通过 WebClient 向我的应用程序返回损坏的字节数组
- amazon-web-services - 通过 docker 为 AWS 中的 firefox 节点创建 Selenium 网络