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
相关产品推荐
相关产品推荐

