You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Amplify GraphQL API:使用beginsWith筛选无法获取10条数据

问题描述

我定义的GraphQL Schema如下:

type Post
  @model {
  createdAt: AWSDateTime!
  hash: String!
  version: Int
    @default(value: "0")
    @index(name: "byVersion", sortKeyFields: ["createdAt"])
}

AWS Amplify自动生成的查询语句:

export const postsByVersionAndCreatedAt = /* GraphQL */ `
  query postsByVersionAndCreatedAt(
    $version: Int!
    $createdAt: ModelStringKeyConditionInput
    $sortDirection: ModelSortDirection
    $filter: ModelPiecePostFilterInput
    $limit: Int
    $nextToken: String
  ) {
    postsByVersionAndCreatedAt(
      version: $version
      createdAt: $createdAt
      sortDirection: $sortDirection
      filter: $filter
      limit: $limit
      nextToken: $nextToken
    ) {
      items {
        hash
        id
        version
        __typename
      }
      nextToken
      __typename
    }
  }
`;

我用来获取前10条数据的调用代码:

const postsByVersionAndCreatedAtResult = await API.graphql({
  authMode: GRAPHQL_AUTH_MODE.AWS_IAM,
  query: postsByVersionAndCreatedAt,
  variables: {
    filter: {
      hash: {
        beginsWith: e.target.value,
      },
    },
    limit: 10,
    sortDirection: "DESC",
    version: 0,
  },
});

调用能正常执行,但只返回3条数据,不是预期的10条。我以为在Schema里创建@index能解决,但没生效,请问需要怎么修改?


解决方案

问题出在过滤逻辑的执行时机和当前索引的设计上:

  • DynamoDB索引过滤机制的限制
    你当前的byVersion索引是以version为分区键、createdAt为排序键。查询时DynamoDB会先取出所有version=0的条目,按createdAt排序后,再对结果做filter过滤hash前缀匹配的条目。这就导致:如果排序后的前N条里只有3条符合hash前缀条件,就只会返回3条,而非先过滤再取10条。

  • 调整索引结构,让过滤条件成为索引的一部分
    要实现先按hash前缀过滤、再取最新10条的需求,需要把version和hash设为复合分区键,createdAt作为排序键。修改后的Schema如下:

type Post
  @model {
  createdAt: AWSDateTime!
  hash: String!
  version: Int
    @default(value: 0)
    @index(name: "byVersionHashCreatedAt", sortKeyFields: ["createdAt"], queryField: "postsByVersionHashCreatedAt")
}

注意:把default的"0"改成数字0,因为version类型是Int,字符串默认值会导致类型不匹配,引发潜在问题。

  • 修改查询参数,利用新索引精准筛选
    Amplify会自动生成新的查询postsByVersionHashCreatedAt,调用时需要把hash的前缀匹配作为键条件(而非filter)传入。这样DynamoDB会直接在索引中定位符合条件的条目,再按createdAt排序取前10条:
const postsResult = await API.graphql({
  authMode: GRAPHQL_AUTH_MODE.AWS_IAM,
  query: postsByVersionHashCreatedAt,
  variables: {
    version: 0,
    hash: {
      beginsWith: e.target.value,
    },
    limit: 10,
    sortDirection: "DESC",
  },
});
  • 核心原因总结
    filter是索引查询完成后的内存过滤,受限于索引返回的条目数量;而键条件是索引查询时的磁盘级筛选,直接定位目标数据,能保证取到足够数量的符合条件的条目。

内容的提问来源于stack exchange,提问作者John DeBord

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 17:45:17