Как отфильтровать вложенный массив GraphQL по полю, возвращаемому в ответе того же запроса? Или как создать отношения GraphQL более чем для одного поля?

Итак, я использую GraphQL с Hasura и Apollo в своем приложении для Android. Приложение связано со спортом, оно хранит несколько наборов очков каждого игрока в нескольких сегментах матча. В моей базе данных Postgres есть следующие таблицы (с соответствующими полями):

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 - это таблица-мост "многие ко многим" между таблицами Segment и Player. Существуют отношения массивов от Match до Segment и от Player до Score.

Я хочу запросить результаты каждого игрока в матче, разделенные сегментами. Ответ, который я хочу, должен иметь следующую структуру:

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

Проблема, с которой я столкнулся, заключается в том, что я не могу найти способ отфильтровать оценки как по PlayerId, так и по SegmentId. Player - Score отношение может дать мне все оценки этого игрока. Или я могу создать связь между Segment и Score, которая даст мне оценку каждого игрока в этом сегменте. Но любой из них все равно оставит мне фильтрацию на стороне клиента.

Я хочу иметь возможность предоставлять данные, возвращаемые в качестве аргумента в предложении where, как показано ниже:

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

Как этого добиться без фильтрации данных на стороне клиента.


person Zain Qureshi    schedule 17.06.2019    source источник


Ответы (1)


Я знаю, что это очень поздно, но запрос будет работать как есть, без второго предложения where

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

Потому что вы получите только игроков, относящихся к этому сегменту, а затем вы получите только очки, связанные с этим игроком для этого сегмента.

Если оценки действительно связаны с сегментом, и вы хотите, чтобы все оценки для этого сегмента, а не все оценки, относящиеся к этому игроку для этого сегмента, вы должны добавить еще одну взаимосвязь.

query PointsQuery($matchId: String!) {
  SegmentQL: segment(where: {matchId: {_eq: $matchId}}) {
    SegmentId: id
    score {
      ...ScoreQL
    }
    segment_player {
      player {
        ...PlayerQL
      }
    }
  }
}
person moto    schedule 06.05.2020
comment
Спасибо за ваш ответ и извините за супер поздний ответ. Я нашел способ решить эту проблему. Увы, ни одно из ваших предложений не сработало бы для меня. - person Zain Qureshi; 06.06.2021
comment
Я должен был упомянуть, что игрок может участвовать более чем в одном матче / сегменте, поэтому, если я буду следовать вашему первому решению, я получу все оценки этого игрока для каждого матча / сегмента. - person Zain Qureshi; 06.06.2021
comment
Что касается вашего второго решения, я уже упоминал в своем вопросе, что я могу получить все оценки в сегменте, используя связь «Сегмент - оценка», но это будет означать, что я должен сопоставить оценки каждому игроку на стороне клиента. Это тоже нехорошо. - person Zain Qureshi; 06.06.2021
comment
В любом случае, спасибо за ответ, так как вы единственный, кто придумал возможное решение. Думаю, мне удалось решить эту проблему, создав связь между таблицами Segment_Player и Score. - person Zain Qureshi; 06.06.2021