如何在 aws-amplify 中对列表查询中的字段进行排序?

How to sort on a field in list query in aws-amplify?

如何在 amplify graphql 中对字段进行排序 api?我正在尝试在获取模型列表时对字段进行排序。

例如:在 listOrder 查询中按 createdDate 排序。

有什么帮助吗?

@key 指令可能就是您想要的。

假设您要按 createdAt 时间戳列出特定客户的 Order,并假设这是您的架构:

type Order @model @key(fields: ["customerEmail", "createdAt"]) {
    customerEmail: String!
    createdAt: String!
    orderId: ID!
}

这将创建一个主索引,其散列键为 customerEmail,排序键为 createdAt,由 AppSync 解析器代表您管理。这将允许您 运行 这个查询:

query ListOrdersForJack {
  listOrders(customerEmail:"jack@gmail.com") {
    items {
      orderId
      customerEmail
      createdAt
    }
  }
}

为什么没有明确的 sort 关键字?排序将自动进行,因为 @key 指定字段 createdAt 应该用作排序键。您可以参考 https://github.com/aws-amplify/amplify-cli/issues/1502 进行类似的讨论。

2021 更新:我尝试了 Yik 提供的解决方案(Amplify 中的某些内容自动填充 createdDate 自动作为 sortKey 提供) ,但 AWS Amplify 中的排序似乎没有像您预期的那样工作。

为了节省其他人的时间,我写了更长的 post 并使用以下模型处理 1 用户,该用户具有 M任何通知。

我使用了“aws-amplify”:“^4.3.1”和“aws-amplify-react-native”:“^5.0.3”。

从 'owner' 对象过滤

我使用了下面的架构(旨在成为一对多关系):

type User
  @model {
  id: ID!
  username: String
  lastname: String
  firstname: String
  description: String
  avatar: String
  externalHandles: [ExternalHandle]
  followerCount: Int
  followingCount: Int
  verifiedEmail: String
  createdDate: AWSTimestamp
  enableMessageRequests: Boolean
  --> notifications: [UserNotification] @connection(keyName: "byUser", fields: ["id"])
}


type UserNotification 
  @model 
  @key(name: "byUser", fields: ["userID", "createdAt"])
  @auth(rules: [{allow: public}, {allow: public}]) {
  id: ID!
  text: String
  ---> userID: ID!
  ---> author: User! @connection(fields: ["userID"])
  clubID: ID  
  club: Club @connection(fields: ["clubID"])
  type: NotificationsType
  seen: Boolean
  time: AWSTimestamp
  createdAt: String!
}

然后我 运行 'amplify mock api' 生成查询并在 GraphiQ 网络控制台中查看它们(+ 我添加了一些虚拟数据)。

现在,如果您想列出来自用户('owner' 对象)的通知,您可以指定排序方向

直接过滤

但是如果您尝试直接为给定用户列出通知(例如,通过使用用户 ID 作为过滤器而不是使用父对象),排序缺少方向

同样如您在右侧所见,结果是 未自动排序 :

为了解决这个问题,我需要更新架构,我在其中添加了 queryField: "userNotificationsByDate" 这将创建一个新的单独查询。请参阅下面的更新模型:

type UserNotification 
 @model @key(name: "byUser", fields: ["userID", "createdAt"], queryField: "userNotificationsByDate") 
 @key(name: "byNotifications", fields: ["userID", "createdAt"]) 

现在您将获得排序结果 - 但您仍然必须指定用户ID/或主键 你在@key指令中定义的。 @Key directive/annotation 使用格式 ["primaryKey", "sortKey"]. 如果将 primaryKey 值留空,查询将失败。使用这个新生成的查询时,请查看以下结果:

直接过滤 - 在所有对象上重复主键

最后,如果您想要列出通知(不知道它们属于哪个用户),您需要使用 在所有持久化对象中相同的主键值定义 @key。请参阅示例模型:

type UserNotification 
  @model 
  @key(name: "justByDate", fields: ["dummyType", "createdAt"])
  @auth(rules: [{allow: public}, {allow: public}]) {
  id: ID!
  createdAt: String!
  dummyType: String!
  ...

然后您需要像这样创建通知(使用相同的主键):

mutation {
  createUserNotification(input: {
   userID: "d69f62fe21b299",
   dummyType: "ShouldBeSameForAllRooms"}) {
    id
  }
}

注意:除了字符串,您还可以在架构中使用 'enum' 作为此虚拟主键。

如果你会使用枚举,比如

enum NotificationsType {
  START_MEETING
  JOINED_ROOM
}

type UserNotification @model 
@key(name: "byUser", fields: ["userID", "createdAt"], queryField: "userNotificationsForSpecifiedUserByDate")
@key(name: "byUser3", fields: ["type", "createdAt"], queryField: "userNotificationsByDate") 
  @auth(rules: [{allow: public}, {allow: public}]) {
  id: ID!
  userID: ID!
  text: String
  clubID: ID
  author: User! @connection(fields: ["userID"])
-> type: NotificationsType!
  seen: Boolean
  time: AWSTimestamp
  createdAt: String!
}

您可以获得属于例如一些组(START_MEETING 或 JOINED_ROOM 在我的示例中)SORTED 使用以下查询:

query MyQuery {
  userNotificationsByTypeSortedBtDate(sortDirection: ASC, type: START_MEETING) {
    items{
      createdAt
    }
  }
}

查看结果: