Graphql 如何访问父查询值以构造新查询?

Graphql 如何访问父查询值以构造新查询?,graphql,javascript,graphql-js,Graphql,Javascript,Graphql Js,在中,我想使用提供给家长的电影查询的坐标构建场馆查询,而在事件中,我想使用家长场馆ID,例如 { movies(coordinates: {latitude: 51.509865, longitude: -0.118092}) { id, venues (coordinates: [parent query coordinates]) { id, events (coordinates: [parent query coordinates], venu

在中,我想使用提供给家长的
电影
查询的
坐标构建
场馆
查询,而在
事件
中,我想使用家长场馆ID,例如

{
  movies(coordinates: {latitude: 51.509865, longitude: -0.118092}) {
    id,
    venues (coordinates: [parent query coordinates]) {
      id,
      events (coordinates: [parent query coordinates], venueId: [parent query venue]) {
        id
      }
    }
  }
}

如何引用父查询参数/结果?

您尝试实现的第一件事(重用参数)可以使用。然而,就我所知,第二件事(将输出值重新用作输入)无法实现。 但是,这两种类型的关系似乎没有正确定义。让我们更详细地了解每一点

使用变量重用参数 TL;DR变量是重用参数的关键概念,但在OP描述的情况下可能并不理想。请参阅下面答案的第二部分。我把它留在这里是为了提供全部细节

定义一次参数并多次使用它们是非常合适的

使用的最小示例如下所示:

query SomePeopleAndCompatriots($numberOfResults: Int) {
  allPeople(first: $numberOfResults) {
    name
    homeworld {
      name
      residents(first: $numberOfResults) {
        name
      }
    }
  }
}
const VenueType = new GraphQLObjectType({
  name: 'Venue'
  id: /* ... */,
  // ...
  events: {
    type: new GraphQLList(EventType),
    description: 'All events happening at this venue',
    resolve: venue => venue.getEvents()
  )
});
resolve: coordinates => allMovies.filter(movie =>
  movie.venues.some(venue => venue.coordinates === coordinates)
)
声明以下变量时:

{ "numberOfResults": 3 }
{ "coordinates": { "latitude": 51.509865, "longitude": -0.118092 } }
在实践中,此API实现了,因此实际的查询稍微复杂一点,但可以随意使用

将为您提供更多关于如何使用GraphQL.js参数的详细信息,但由于您没有提供与模式声明相对应的代码,因此需要调整细节

在您的情况下,我认为您已经将
坐标定义为输入类型。假设您调用了if
CoordinationInput
,您的查询现在看起来像(故意省略
venueId
,请参见下面回答的其余部分):

传递相应的变量:

{ "numberOfResults": 3 }
{ "coordinates": { "latitude": 51.509865, "longitude": -0.118092 } }
这将满足您的期望,但这可能不是最好的路线,我们将在下面看到

改善你的人际关系 根据我掌握的信息,您的查询显示,
电影
场馆
活动
背后的类型彼此不了解。这意味着您的模式无法利用GraphQL的所有功能。将您的模式视为一棵树,
事件
场馆
的子级,
场馆
电影
的子级

对于
venueId
,您甚至不需要它。 让我们对您的模式声明进行一些假设。您的
VenueType
如下所示:

query SomePeopleAndCompatriots($numberOfResults: Int) {
  allPeople(first: $numberOfResults) {
    name
    homeworld {
      name
      residents(first: $numberOfResults) {
        name
      }
    }
  }
}
const VenueType = new GraphQLObjectType({
  name: 'Venue'
  id: /* ... */,
  // ...
  events: {
    type: new GraphQLList(EventType),
    description: 'All events happening at this venue',
    resolve: venue => venue.getEvents()
  )
});
resolve: coordinates => allMovies.filter(movie =>
  movie.venues.some(venue => venue.coordinates === coordinates)
)
当您查询来自
场馆
的所有结果的
事件
时,您实际上请求解析器对给定的
场馆
调用
getEvents()
,您可以对其进行操作。我不知道您的实现,但它可以简单地执行
vention.events
,或
Event.findAllByVenue(venue.id)
,等等。在这里,您可以确保仅检索特定场所的事件,而不是存储中的所有事件

将为您提供有关如何执行此操作的更多详细信息

类似地,
MovieType
应该具有解析为
movie=>movie.getvinces()
,这就是为什么我的答案的第一部分不适合您的情况。最后,您的查询应该如下所示:

query MoviesAndVenuesAndEvents($coordinates: CoordinatesInput) {
  movies(coordinates: $coordinates) {
    id
    venues {
      id
      events {
        id
      }
    }
  }
}
这基本上是说:“根据这些坐标给我取所有电影,对于每部电影,给我所有场地和这些场地的所有活动。”

如果您试图获取的是在给定区域内播放的所有电影(目前只关注电影和场地,但您可以将其推断为事件),那么您的查询可能是:

venues(coordinates: $coordinates) {
  id
  movies
}
但最后一个示例可能会给您提供必须在客户端上展平的副本。要首先关注电影,您可以使用前面的示例,确保您的
movies
解析器仅检索传递坐标的电影。再次对后端进行完整的假设,可能如下所示:

query SomePeopleAndCompatriots($numberOfResults: Int) {
  allPeople(first: $numberOfResults) {
    name
    homeworld {
      name
      residents(first: $numberOfResults) {
        name
      }
    }
  }
}
const VenueType = new GraphQLObjectType({
  name: 'Venue'
  id: /* ... */,
  // ...
  events: {
    type: new GraphQLList(EventType),
    description: 'All events happening at this venue',
    resolve: venue => venue.getEvents()
  )
});
resolve: coordinates => allMovies.filter(movie =>
  movie.venues.some(venue => venue.coordinates === coordinates)
)

嗨@Gajus,我的回答解决了你的问题吗?:)