amplify-cli: Using @key directive sorting doesn't work

I want to get a certain number of image sets with the top ranking, this is my schema

type Set
  @model
  @key(name: "ByRanking", fields: ["ranking"], queryField: "byRanking") {
	id: ID!
	user: String!
	ranking: Int!
	pictures: [Picture!]! @connection
}

I get a generated query called byRanking, but it requires to specify the exact ranking, in which case I don’t understand what it actually sorts. If I only get items with ranking value of X, there is nothing to sort…

query GetSetsByRanking {
  byRanking(sortDirection:ASC, ranking: 5) { # Throws an error without the ranking
    items {
      id
      ranking
    }
  }
}

If I simply do @key(fields: ["ranking"]) I get the ID field replaced by ranking and I don’t have a unique ID to each set anymore. I need it to connect pictures to the set with @connection.

What am I doing wrong? How should I first sort by ranking and then do limit: X?

This is the auto-generated query:

query ByRanking(
  $ranking: Int
  $sortDirection: ModelSortDirection
  $filter: ModelSetFilterInput
  $limit: Int
  $nextToken: String
) {
  byRanking(
    ranking: $ranking
    sortDirection: $sortDirection
    filter: $filter
    limit: $limit
    nextToken: $nextToken
  ) {
    items {
      id
      user
      ranking
      pictures {
        nextToken
      }
    }
    nextToken
  }
}

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 22 (1 by maintainers)

Most upvoted comments

@ilyador with the following schema you can achieve what you are looking for:

type Set
@model
@key(name: "ByRanking", fields: [ "type", "ranking" ], queryField: "getSetsByRanking")
{
	id: ID!
	type: String!
	user: String!
	ranking: Int!
}

I’ve excluded the Pictures, since it is indifferent for the problem you have.

This schema will create a GSI named ByRanking and enables you to query AND even filter on ranking if needed and of course you can sort.

Notice the type field, that acts like the HASH key for the GSI, you must set it to ‘Set’ always or you can update the resolvers to get it handled for you.

After you create some data with a mutation like this:

mutation {
  createSet(input:
  {
    id: "1"
    type: "Set"
    user: "User1"
    ranking: 5
  })
  {
    id
  }
}

This query will return you all the items in descending order by ranking and with paging support:

query GetByRanking {
  getSetsByRanking(type: "Set", sortDirection: DESC)
  {
    items
    {
      id
      type
      user
      ranking
    }
  }
}

If you just need the data which has a lower rating than 5 you can add filtering to it:

query GetByRanking {
  getSetsByRanking(type: "Set", ranking: { lt: 5 }, sortDirection: DESC)
  {
    items
    {
      id
      type
      user
      ranking
    }
  }
}

I hope this sample solves your problem.

@attilah yes! The type was the missing piece.

The first field in your schema (the partition key) needs to be the same for all items. If you are using the setId, this is incorrect, as the setId is different for each item. This is what I described in a previous comment. It is easier to help if you share your schema, because right now I don’t know what you key directives look like.