How to filter GraphQL nested array on field returning in same query's response? Or how to create GraphQL relationship on more than one field?

Viewed 1786

So I'm using GraphQL with Hasura and Apollo in my Android application. The application is related to sports, it stores multiple score sets of each player in multiple segments of a match. My Postgres database has following tables (with concerned fields):

Match (id, other_fields...)
Segment (id, match_id, other_fields...)
Segment_Player (id, segment_id, player_id)
Player (id, other_fields...)
Score (id, segment_id, player_id, other_fields...)

Segment_Player is a many to many bridge table between Segment and Player tables. There are array relationships from Match to Segment and from Player to Score.

I want to query scores of each player in a match separated by segments. Response I want should be like following structure:

Match
--Segment
----Player
------Score

The problem I'm facing is that I cannot find a way to filter scores on both PlayerId and SegmentId. Player - Score relation can give me all scores of that player. Or I can create a relation between Segment and Score which will give me scores of every player in that segment. But either of these will still leave me with filtering to do on client side.

What I want is to be able to provide data returning in response as argument in where clause like below:

query PointsQuery($matchId: String!) {
  SegmentQL: segment(where: {matchId: {_eq: $matchId}}) {
    SegmentId: id
    segment_player {
      player {
        ...PlayerQL
        scores(where: {segmentId: {_eq: SegmentId}}) {
          ...ScoreQL
        }
      }
    }
  }
}

How to achieve this without filtering data on client side.

1 Answers

I know this is super late, but the query will work as-is, without the second where clause

query PointsQuery($matchId: String!) {
  SegmentQL: segment(where: {matchId: {_eq: $matchId}}) {
    SegmentId: id
    segment_player {
      player {
        ...PlayerQL
        scores {
          ...ScoreQL
        }
      }
    }
  }
}

Because you will only get the players related to that segment and then you will only get the scores related to that player for that segment.

If scores are actually related to a segment and you want all scores for that segment, instead of all scores related to that player for that segment, you should add another relationship

query PointsQuery($matchId: String!) {
  SegmentQL: segment(where: {matchId: {_eq: $matchId}}) {
    SegmentId: id
    score {
      ...ScoreQL
    }
    segment_player {
      player {
        ...PlayerQL
      }
    }
  }
}
Related