我有一个应用程序,该应用程序具有许多相关类型。就像这样:
type Person {
Name: String!
Address: Address!
Family: [Person!]!
Friends: [Person!]!
Job: Occupation
Car: Car
}
type Address {...}
type Occupation {...}
type Car {...}
(不必担心具体类型...)
无论如何,这些都存储在数据库的许多表中。
其中一些查询很少使用且速度很慢。举例来说,假设世界上有数十亿辆汽车,并且花时间寻找我们感兴趣的人拥有的汽车。对“ getPerson”的任何查询都必须满足完整的架构,然后graphql会将其缩减为必填字段。但是由于那很慢并且可以请求 ,所以即使数据大部分时间被丢弃,我们也必须执行查询。
我只看到2种解决方案。
a)每次都执行查询,它总是很慢
b)设置2个独立的查询选项。一个用于“ getPerson”,一个用于“ getPersonWithCar”,但随后您将无法重用该架构,现在Person
被定义了两次。一次就汽车而言,一次就没有汽车。
是否有一种方法可以指示在Query
请求的字段中是否存在某个字段?这样我们就可以说
if (query.isPresent("Car")) {
car = findCar();
} else {
car = null;
}
答案 0 :(得分:0)
如果您的存储层是关系数据库,则通常有两种方法来处理模式中的关系,每种方法各有利弊。一种方法是简单地让每个“关系”字段从适当的表中获取数据。因此,给定这样的Query
类型:
type Query {
getPerson: Person
}
getPerson
的解析器仅从数据库中的persons
表中提取一行。然后,family
字段的解析程序将获取该关系的相关行,friends
的解析程序将获取那些相关行,依此类推。
很明显,这可以迅速增加每个请求您要进行的数据库调用的数量,并且由于某些查询将顺序而不是并行进行,因此会影响性能。另一方面,如果不请求这些字段,则决不会调用解析器。此解决方案通常更适合其他数据源,例如从其他API提取数据,但在某些情况下仍可以加快查询速度。
另一种方法是在getUser
的解析器中获取所需的所有内容。当然,获取所有可能的关系将是昂贵的,并且可能是不必要的。幸运的是,在GraphQL.js中,传递给解析器的fourth paramete r是一个“信息”对象,用于描述整个GraphQL请求。您可以解析该对象以确定请求哪些字段,并相应地微调数据库查询(或ORM方法调用)。
有一篇不错的文章here,介绍了信息对象本身的结构以及如何解析它。对此进行更深入的讨论可能超出了此问题的范围。如果您不想自己解析信息对象,则有许多可用的软件包可以为您完成工作(我推荐的软件包是graphql-parse-resolve-info
)。