Search code examples
react-nativegraphqlaws-amplifygraphql-jsaws-amplify-cli

How to Filter List/Queries With AND/OR operators AWS Amplify JavaScript GraphQL


I am new to using AWS Amplify and GraphQL. Also just started building out React Native App - which is a lot of fun!

I have a table called TimePeriods schema for it looks like this

type TimePeriod @model {
  id: ID!
  name: String!
  startYear: String!
  endYear: String!,
  artworks: [ArtWorkTimePeriod] @connection (name: "TimePeriodArtWorks") #Many to Many Relationship
  artists: [ArtistTimePeriod] @connection (name: "TimePeriodArtists") #Many to Many Relationship
}

In the queries file generated by amplify I have a function called listTimePeriods.

export const listTimePeriods = /* GraphQL */ `
  query ListTimePeriods(
    $filter: ModelTimePeriodFilterInput
    $limit: Int
    $nextToken: String
  ) {
    listTimePeriods(filter: $filter, limit: $limit, nextToken: $nextToken) {
      items {
        id
        name
        startYear
        endYear
        artworks {
          nextToken
        }
        artists {
          nextToken
        }
      }
      nextToken
    }
  }
`;

What I am trying to do is filter this by condition for example I'd like to get list of all Time Periods where IDs equal 1, 2 or 3. I was assuming it could be done in a following manner

export async function GetTimePeriodsByIds(idArr=[]){
    let filter = {
        id: {
            eq: [1,2,3]
        }
    };
    return await API.graphql(graphqlOperation(listTimePeriods, {limit: 20, filter:filter}));
}

but I do not think you can do that. If you have any kinds of solution regarding this, it would mean a lot - even just the insight like

  1. If it does not work at all - is there any reason why they decided not to implement it?
  2. Would it be better in the case to use a for loop and call

    await API.graphql(graphqlOperation(getTimePeriod, {id: id}));

or would it be better to get the whole list and filter it out myself? And by better I mean efficiency - maybe it depends on the number of data that will be listed in the TimePeriod table (if many entries then get one by one from DB, if small number of entries get all and filter it out?)


Solution

  • Hello to everyone looking into this question - after a lot of research I found out that it can be achieved like this:

         let filter = {
                or: [
                    {
                        id: {eq:1}
                    },
                    {
                        id: {eq:2}
                    }]
            };
    return await API.graphql(graphqlOperation(listTimePeriods, {limit: 20, filter:filter}));
    

    in order to find out what you can do with AND and OR operations with GraphQL List you need to similar definition in your files

    input ModelTimePeriodFilterInput {
      id: ModelIDInput
      name: ModelStringInput
      startYear: ModelStringInput
      endYear: ModelStringInput
      and: [ModelTimePeriodFilterInput]
      or: [ModelTimePeriodFilterInput]
      not: ModelTimePeriodFilterInput
    }
    

    which should be located in backend/api/projectname/build/schema.graphql

    This means that in a similar manner you can write AND and OR filters. Hope this helps - I wish AWS Documentation made this easier to understand

    If you have a similar question but cannot find your answer here maybe this post will help - GraphQL: Filter data in an array