首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >提高4级嵌套列表的Graphql (石墨烯-django)性能

提高4级嵌套列表的Graphql (石墨烯-django)性能
EN

Stack Overflow用户
提问于 2022-10-21 13:00:31
回答 1查看 30关注 0票数 0

我将Django 4与石墨烯-Django 3结合使用,我需要构造一个响应,这个响应必须是4个级别的列表,底层是一个字典。在这里实现

代码语言:javascript
复制
class FailureSensorType(DjangoObjectType):
      class Meta:
         model = FailureSensor
      spectra = graphene.Field(SpectraGraphType)
      ...
      rest of fields


class SpectraGraphType(graphene.ObjectType):
   name = graphene.List(graphene.String)
   spectra_z = graphene.List(graphene.List(graphene.List(SpectraZGraphType)))


class SpectraZGraphType(graphene.ObjectType):
   _id = graphene.String(required=False)
   collection_name = graphene.String(required=False)
   values = graphene.List(graphene.Float, required=False)
   values_names = graphene.List(graphene.Int, required=False)
   sidebands = graphene.List(graphene.Float, required=False)
   rpm_detected = graphene.Int(required=False)
   anomaly = graphene.Int()


def resolve_spectra(self, info):
        if self.anomaly_type == "spectra":
            spectra_name = set()
            for graph_y in self.get_map_Y():
                spectra_name.add(str(self.id) + '-' + graph_y.split()[-1])

            spectra_z_list = list()
            spectra_z_list_new = list()
            for i, x in enumerate(np.split(self.get_map_Z(), id_z)):
                spectra_z_list.append(x.tolist())


            for spectra_z in spectra_z_list:
                zero_index_list = list()
                for index_obj, graph_z_obj in enumerate(spectra_z):
                    zero_index = list()
                    for i, graph_z_value in enumerate(graph_z_obj):
                        if graph_z_value != '{"anomaly": 0}':
                            zero_index.append(i)

                    zero_index_list.append(zero_index)

                new_z_list = list() 
                for z_obj in spectra_z:
                    new_z = [v for i, v in enumerate(z_obj) if i in zero_index_set]
                    z_dict_list = list()
                    for dict_string in new_z:
                        r = json.loads(dict_string.replace("|", ",").replace("(", "[").replace(")", "]"))
                        if "_id" not in r:
                            r["_id"] = ""
                        if "collection_name" not in r:
                            r["collection_name"] = ""    
                        if "rpm_detected" not in r:
                            r["rpm_detected"] = -1    
                        if "values" in r:
                            r["values"] = json.loads(r["values"])
                        else:
                            r["values"] = []
                        if "values_names" in r:
                            r["values_names"] = json.loads(r["values_names"])
                        else:
                            r["values_names"] = []
                        if "sidebands" in r:
                            r["sidebands"] = json.loads(r["sidebands"])
                        else:
                            r["sidebands"] = []
                        z_dict_list.append(r)
                    new_z_list.append(z_dict_list)

                spectra_z_list_new.append(new_z_list)
                
            return {
                "name": spectra_name,
                "spectra_z": spectra_z_list_new
            }

这是graphql查询:

代码语言:javascript
复制
inspectSensorFailureBySystem(){
 failureSensors{
  anomalyType
  failureSensors{
    spectra{
      name
      spectraZ {
        Id
        collectionName
        rpmDetected
        anomaly
        values
        valuesNames
        sidebands
        
      }
    }
  }
}

此查询的结果是:

代码语言:javascript
复制
{
 "data": {
   "inspectSensorFailureBySystem": [
     {
       "failureSensors": [
         {
        "anomalyType": "spectra",
        "failureSensors": [
          {
            "spectra": {
              "name": [
                "15339-envelope_spectra",
                "15339-envelope_spectra_timedomain",
                "15339-spectra_timedomain",
                "15339-spectra"
              ],
              "spectraZ": [
                [
                  [
                    {
                      "Id": "628bd17db4aff3060810a726",
                      "collectionName": "spectrum",
                      "rpmDetected": -1,
                      "anomaly": -1,
                      "values": [],
                      "valuesNames": [],
                      "sidebands": []
                    },
                    ...
                    {
                      "Id": "62e8d3119aa606584e88b228",
                      "collectionName": "timedomain",
                      "rpmDetected": 1256,
                      "anomaly": 1,
                      "values": [
                        261.1224,
                        522.2448,
                        783.3672,
                        1044.4896,
                        1305.612,
                        1566.7344,
                        1827.8568,
                        2088.9792,
                        2872.3464,
                        3133.4688
                      ],
                      "valuesNames": [
                        1,
                        2,
                        3,
                        4,
                        5,
                        6,
                        7,
                        8,
                        11,
                        12
                      ],
                      "sidebands": []
                        }
                      ]
                    ]
                  ]
                }
              }
            ]
          }
        ]
      }
    ]
  }
}

数据直接来自一个字符串化字典列表(spectra_z),该列表在前一个解析器中被解析,并且工作速度相当快(小于0.2s)。因此,从数据库中检索数据,然后从string解析到所需的嵌套列表和最终字典是非常快速的。

但是在解析器完成并将结果传递给GraphGL引擎之后,GraphGL需要30多个时间来解析给定的结果并发送最终的响应。

另一方面,如果我只是从数据库(spectra_z)获得字符串化的值,并将它们作为字符串传递(不涉及嵌套列表),那么显然GraphGL响应非常快。

我不是GraphGL方面的专家,我想知道如何加快graphene来更快地解析这个响应(因为30秒来获得响应是不可接受的)。是否存在任何类型的设置参数来加快它的速度或任何诡计?

编辑的

我遵循了@MichelFloyd的建议,所以现在的结构如下:

代码语言:javascript
复制
class FailureSensorType(DjangoObjectType):
    class Meta:
        model = FailureSensor
    spectra = graphene.Field(SpectraGraphType)

    def resolve_spectra(self, info): <-- CHANGED
        return SpectraGraphType(id=self.id)

class SpectraGraphType(graphene.ObjectType): <-- CHANGED
id = graphene.Int()
name = graphene.List(graphene.String)
spectra_z = graphene.List(graphene.List(graphene.List(SpectraZGraphType)))


def resolve_name(self, info, **kwargs):
    self = FailureSensor.objects.get(id=self.id)
    if self.anomaly_type == "spectra":
        spectra_name = set()
        for graph_y in self.get_map_Y():
            spectra_name.add(str(self.id) + '-' + graph_y.split()[-1])
    return spectra_name


def resolve_spectra_z(self, info):
    self = FailureSensor.objects.get(id=self.id)
    if self.anomaly_type == "spectra":
        sections = 4
        z_len = len(self.get_map_Z()) // sections

        id_z = list(range(z_len, z_len * (sections + 1), z_len))[:-1]

        spectra_z_list = list()
        spectra_z_list_new = list()
        for i, x in enumerate(np.split(self.get_map_Z(), id_z)):
            spectra_z_list.append(x.tolist())


        for spectra_z in spectra_z_list:
            zero_index_list = list()
            for index_obj, graph_z_obj in enumerate(spectra_z):
                zero_index = list()
                for i, graph_z_value in enumerate(graph_z_obj):
                    if graph_z_value != '{"anomaly": 0}':
                        zero_index.append(i)

                zero_index_list.append(zero_index)

            zero_index_set = set()
            for zero_index in zero_index_list:
                for zero in zero_index:
                    zero_index_set.add(zero)

            new_z_list = list() 
            for z_obj in spectra_z:
                new_z = [v for i, v in enumerate(z_obj) if i in zero_index_set]
                z_dict_list = list()
                for dict_string in new_z:
                    z_dict_list.append(SpectraZGraphType(text=dict_string)) <--- UPDATED TO PASS LIST OF STRINGIFIED VALUES
                new_z_list.append(z_dict_list)
                #new_z_list.append(new_z)

            spectra_z_list_new.append(new_z_list)
            
        return spectra_z_list_new

    return None

新的底层解析器:

代码语言:javascript
复制
class SpectraZGraphType(graphene.ObjectType):
    text = graphene.String(required=False)
    _id = graphene.String(required=False)
    collection_name = graphene.String(required=False)
    values = graphene.List(graphene.Float, required=False)
    values_names = graphene.List(graphene.Int, required=False)
    sidebands = graphene.List(graphene.Float, required=False)
    rpm_detected = graphene.Int(required=False)
    anomaly = graphene.Int()

def resolve__id(self, info):
    r = json.loads(self.text.replace("|", ",").replace("(", "[").replace(")", "]"))
    if "_id" not in r:
        r["_id"] = ""
    return r["_id"]
def resolve_collection_name(self, info):
    r = json.loads(self.text.replace("|", ",").replace("(", "[").replace(")", "]"))
    if "collection_name" not in r:
        r["collection_name"] = ""    
    return r["collection_name"]

def resolve_rpm_detected(self, info):
    r = json.loads(self.text.replace("|", ",").replace("(", "[").replace(")", "]"))
    if "rpm_detected" not in r:
        r["rpm_detected"] = -1    
    return r["rpm_detected"]

def resolve_values(self, info):
    r = json.loads(self.text.replace("|", ",").replace("(", "[").replace(")", "]"))
   
    if "values" in r:
        r["values"] = json.loads(r["values"])
    else:
        r["values"] = []
    return r["values"]

def resolve_values_names(self, info):
    r = json.loads(self.text.replace("|", ",").replace("(", "[").replace(")", "]"))
    if "values_names" in r:
        r["values_names"] = json.loads(r["values_names"])
    else:
        r["values_names"] = []
    return r["values_names"]

def resolve_sidebands(self, info):
    r = json.loads(self.text.replace("|", ",").replace("(", "[").replace(")", "]"))
    if "sidebands" in r:
        r["sidebands"] = json.loads(r["sidebands"])
    else:
        r["sidebands"] = []

    return r["sidebands"]

def resolve_anomaly(self, info):
    r = json.loads(self.text.replace("|", ",").replace("(", "[").replace(")", "]"))

    return r["anomaly"]

它仍然需要大约30秒的时间来装载。我不确定resolver_spectra_z是否正常。

EN

回答 1

Stack Overflow用户

发布于 2022-10-23 22:44:31

我建议如下:

  1. 为频谱定义一个解析器,该解析器只返回名称数组
  2. ,为spectraZ定义一个解析器,该解析器只返回spectraZ list
  3. ,为spectraZ对象中的所有字段定义单个解析器。这将避免冗长的if语句,在这些语句中,您实际上是通过键
  4. 让GraphQL将所有结果合并到返回对象

中解析一个字段。

如果不是所有嵌套字段都是客户端请求的话,这将带来额外的好处,即不会过度计算所有嵌套字段。因为它是,即使你只是想要的名字,其他一切都会被计算,以及。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74154000

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档