在Redis上存储和访问复杂JSON对象的最快和最佳方法

时间:2018-07-26 12:38:52

标签: python json redis hashset rejson

我一直在使用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

1 个答案:

答案 0 :(得分:0)

与其将复杂的json存储在redis中,还需要使用redis数据结构将其逐段存储。以这种方式存储时,请记住在检索数据时需要执行的查询。这将带您正确使用不同的redis数据结构,以最大程度地缩短查询执行时间。