GraphQL:一个大查询与大量小查询

时间:2019-03-22 01:52:40

标签: node.js graphql apollo apollo-client apollo-server

我知道这个问题和时间一样久远了-他们不是万灵丹。但是我认为那里可能会有一个坚实的模式,我不想发明轮子。

考虑以下两个架构选项:

方法1)我原来的实现方式

type Query {
  note(id: ID!): Note
  notes(input: NotesQueryInput): [Note!]!
}

方法2)我目前的实验方法

type DatedId {
  date: DateTime!
  id: ID!
}

type Query {
  note(id: ID!): Note
  notes(input: NotesQueryInput): [DatedId!]!
}

区别是:

使用方法1)便笺查询将返回可能较大的便笺对象的列表

使用方法2)注释查询将返回轻得多的有效载荷,但随后需要执行 n 个附加查询

所以我的问题是带有内存缓存的Apollo Client / Server堆栈,这是最好的方法。使用可扩展服务器来实现响应式客户端。


笔记
  • 使用方法1-我的500mb dyno(heroku服务器)内存不足。

  • 我希望无论采用哪种方法,我都将使用connection / edge pattern

  • 进行分页
  • graphql服务器主要是为我自己的前端服务。

1 个答案:

答案 0 :(得分:2)

如果服务器上的内存用完了,可能是时候升级了。如果现在内存不足,请想象一下,当有多个用户访问端点时会发生什么情况。

解决该特定问题的另一种方法是将查询分解为几个较小的查询。但是,您提出的方法存在两个问题:

  • 您将最终以更多的请求重击服务器和数据库
  • 您的用户界面可能需要更长的加载时间,具体取决于是否需要立即呈现所请求的数据
  • 处理其中一个请求失败或尝试重试失败请求的情况可能很困难

您已经建议添加分页,并且我认为将单个大型查询分解为较小的查询是一种更好的方法。分页不仅可以带来更好的用户体验,而且可以通过限制页面大小来有效地限制给定查询的大小。

您可能会考虑探索的另一个选择是使用deferred queries。此实验功能是专门为增加昂贵的查询而添加的。通过将def clean (A, t, dt): # function for making A binary for t+-dt # t is the target value I want in the matrix A with tolerance dt new_A = np.copy(A) new_A[np.logical_and(new_A > t-dt, new_A < t+dt)] = -1 new_A[new_A != -1] = 0 new_A[new_A == -1] = 1 return (new_A) def get_surface (X, Y, Z, new_A): x_vals = [] y_vals = [] z_vals = [] # Retrieve (x,y,z) coordinates of surface for i in range(new_A.shape[0]): for j in range(new_A.shape[1]): for k in range(new_A.shape[2]): if new_A[i,j,k] == 1.0: x_vals.append(X[i,j,k]) y_vals.append(Y[i,j,k]) z_vals.append(Z[i,j,k]) return (np.array(x_vals), np.array(y_vals), np.array(z_vals)) cleaned_A = clean (A, t=2.5, dt=0.001) x_f, y_f, z_f = get_surface (X, Y, Z, cleaned_A ) fig = plt.figure() ax = fig.add_subplot(111, projection='3d', aspect='equal') ax.scatter(x_f, y_f, z_f, color='g', s=1) 类型上的一个或多个字段推迟,可以有效地最初为它们返回null,并在它们最终解析之后在第二个“补丁”响应中向下发送它们的值。这对于解析成本很高的字段非常有用,但对于返回大量数据的字段也可能有帮助。