How to sort by date(createdAt) on a field in list query in aws-amplify?
Asked Answered
C

3

7
type Test @model @key(fields: ["id", "createdAt"]) {
  id: ID!
  name: String
  createdAt: String!
}

This model created queries:

getTest(createdAt: String!id: ID!): Test

listTests(
  createdAt: ModelStringKeyConditionInput
  filter: ModelTestFilterInput
  id: ID
  limit: Int
  nextToken: String
  sortDirection: ModelSortDirection
): ModelTestConnection

What should the scheme look like to request a list sorted by date?

Consul answered 2/10, 2019 at 14:29 Comment(1)
Added code formattingGoldeye
P
6

When @key specifies multiple fields, the first field is used as the HASH key and subsequent fields as the SORT key.

https://aws-amplify.github.io/docs/cli-toolchain/graphql#key

It is possible to list sorted items which have the same HASH key. For example, listing all comments by a user:

type Comment
  @model
  @key(fields: ["userId", "createdAt"]) {
    userId: ID!
    createdAt: String!
    text: String
}

Assuming you're using AWS Amplify's GraphQL client, this will list all comments by a user, sorted newest first:

import { API, graphqlOperation } from 'aws-amplify';
import { listComments } from '@/graphql/queries';

export default async function listCommentsForUser(userId) {
  const queryParams = {
    userId,
    sortDirection: 'DESC',
  };

  const operation = graphqlOperation(listComments, queryParams);

  return API.graphql(operation);
}

To list comments since a specified date, newest first, change the query params to include a range query:

const queryParams = {
    userId,
    sortDirection: 'DESC',
    createdAt: { gt: timestamp },
  };
Publicspirited answered 1/5, 2020 at 15:19 Comment(2)
createdAt: AWSDateTime! instead of String!Nyhagen
@key is not available anymore, how can this be done with the new API?Eft
A
1

with new API, it will look something like these:

type Comment @model {
    userId: ID! @index(name:"byUserId",sortKeyFields:["createdAt"],queryField:["getCommentsByUser"])
    createdAt: String!
    text: String
}
Alisun answered 8/7, 2022 at 15:40 Comment(2)
Why would the @index be on the userId field and not on the createdAt field?Thiourea
@neuquen, here it is assumed that user will need to fetch all the comments based on userId and ordered by createdAt timestamp/string. You can add GSIs if you have multiple use cases.Alisun
T
0

Amplify 2024 (using @index):

The key here is that the question asks for a list query. This means that we can't just add an @index to the field we want to sort by, as we would then need to supply an id (or whatever else the unique primary key is set to).

The solution, per the Amplify docs is here:

type Person @model{
  name: ID!
  birthday: AWSDateTime!
  type: String @default(value: "Person") @index(name: "peopleByBirthday", queryField: "peopleByBirthday", sortKeyFields: ["birthday"]) 

The idea here is that we set up a field that will have a consistent value across all entries (established by setting a default) and then query against that field as the primary key.

This is described in the AWS documents here: https://docs.amplify.aws/javascript/build-a-backend/graphqlapi/best-practice/query-with-sorting/

You might think that this is a bit redundant because there should already be a __typename field. I'd agree but the redundant field solution was provided by an Amplify team member via github and the discussion can be found here: https://github.com/aws-amplify/amplify-category-api/issues/45

Tideland answered 23/1 at 14:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.