使用NestJS 9+dynamoose查询DynamoDB报错:找不到查询索引
问题解决:NestJS + Dynamoose Query 报错 'Index can't be found for query.'
错误原因
DynamoDB 的 Query 操作必须依赖哈希键(Hash Key)——要么是主表的 Hash Key,要么是全局二级索引(GSI)的 Hash Key。你当前的代码仅调用了 .query(),未指定要查询的哈希键字段及匹配条件,导致 Dynamoose 无法确定使用哪个索引/主表执行查询,因此抛出索引未找到的错误。
而 Scan 是全表扫描,不依赖索引,所以能正常运行,但它不支持基于索引的排序,且性能远低于 Query。
你的 Schema 分析
从你提供的 Schema 来看:
- 主表结构:Hash Key 为
music,Range Key 为id - 两个 GSI:
songCodeIndex:Hash Key 为songCode,无 Range KeymusicIndex:Hash Key 为music,Range Key 为id(与主表主键结构完全一致,属于冗余索引,可考虑删除)
解决方案
根据你的业务需求,选择以下任意一种方式修正代码:
方案1:基于主表主键查询(推荐,无冗余索引)
如果你的查询是针对特定 music 值下的条目,直接使用主表的主键索引:
const pagination = formatPagination(basePagination); // 必须指定主表的 Hash Key(music)及匹配条件 const query = this.baseRepo .query('music') .eq('你要查询的music值') // 替换为实际业务的music匹配值 .limit(+pagination.limit) .sort(pagination.sort); // 排序基于主表的 Range Key(id) if (pagination.page > 1) { query.startAt(basePagination.keyItem); } try { const result = await query.exec(); return result; } catch (err) { // 按需处理错误,比如日志上报或返回业务错误码 throw err; }
方案2:基于 GSI 查询(如果需要按 songCode 维度查询)
如果你的查询是针对特定 songCode 值,需要指定使用 songCodeIndex 这个 GSI:
const pagination = formatPagination(basePagination); const query = this.baseRepo .query('songCode') .using('songCodeIndex') // 明确指定要使用的GSI名称 .eq('你要查询的songCode值') // 替换为实际业务的songCode匹配值 .limit(+pagination.limit); // 注意:songCodeIndex 没有设置 Range Key,因此 .sort() 无法生效 // 如果需要基于该GSI排序,需修改Schema给songCodeIndex添加Range Key(比如id) if (pagination.page > 1) { query.startAt(basePagination.keyItem); } try { const result = await query.exec(); return result; } catch (err) { throw err; }
关键注意事项
- 所有
Query操作必须指定哈希键的匹配条件(eq/beginsWith等),否则无法确定查询维度 - 使用 GSI 时,必须通过
.using('索引名')明确指定,避免 Dynamoose 匹配错误 - 排序功能仅在查询的索引(主表或 GSI)包含 Range Key 时有效,排序顺序基于该 Range Key
- 你定义的
musicIndex与主表主键结构重复,属于冗余资源,建议删除以节省 DynamoDB 存储及读写费用
内容的提问来源于stack exchange,提问作者AnhDao
相关产品推荐
相关产品推荐

