如何查询DynamoDB电影示例数据库以按类型检索对应电影数据
核心原因
DynamoDB的全局二级索引(GSI)仅支持字符串、数字、布尔等标量类型作为索引键,不支持列表、映射这类复杂类型,这就是你找不到直接给genres列表字段建GSI示例的原因。
需求1:检索全表所有genres的列表
根据你的表数据规模选择方案:
- 数据量小于1万条、查询频率极低:直接全表扫描提取去重即可,扫描时指定
ProjectionExpression仅返回info.genres字段降低读取成本,Node.js示例代码如下:
const { DynamoDBClient, ScanCommand } = require("@aws-sdk/client-dynamodb"); const { unmarshall } = require("@aws-sdk/util-dynamodb"); const client = new DynamoDBClient({ region: "你的AWS区域" }); const getAllGenres = async () => { const genreSet = new Set(); let lastEvaluatedKey = null; do { const scanRes = await client.send(new ScanCommand({ TableName: "你的电影表名", ProjectionExpression: "info.genres", ExclusiveStartKey: lastEvaluatedKey })); scanRes.Items.forEach(item => { const movieData = unmarshall(item); movieData.info?.genres?.forEach(g => genreSet.add(g)); }); lastEvaluatedKey = scanRes.LastEvaluatedKey; } while (lastEvaluatedKey); return Array.from(genreSet); }
- 数据量大、查询频率高:单独维护一张
Genres汇总表,写入/修改/删除电影条目时同步更新该表的类别列表,查询时直接读该表即可,读取成本为O(1)。
需求2:输入指定genre检索对应电影标题
根据查询频率选择方案:
方案A:高频查询场景(推荐)
调整数据建模,支持建GSI实现高效查询:
你可以二选一调整:
- 不修改原主表:单独建一张
电影类别关联表,仅存储genre(分区键)、year、title三个字段,一部电影对应N个类别就写入N条数据,查询时直接按genre等值查询即可批量获取对应电影标题。 - 调整原主表结构:在写入电影数据时新增
genre标量字段,一部电影对应N个类别就写入N条主表数据,为genre字段创建GSI后直接查询该GSI即可。
方案B:低频查询场景
如果该需求触发频率极低,不愿意调整数据结构,可以用全表扫描加过滤的方式实现,Node.js示例代码如下:
const getMoviesByGenre = async (targetGenre) => { const result = []; let lastEvaluatedKey = null; do { const scanRes = await client.send(new ScanCommand({ TableName: "你的电影表名", ProjectionExpression: "title", FilterExpression: "contains(info.genres, :targetGenre)", ExpressionAttributeValues: { ":targetGenre": { S: targetGenre } }, ExclusiveStartKey: lastEvaluatedKey })); scanRes.Items.forEach(item => result.push(unmarshall(item).title)); lastEvaluatedKey = scanRes.LastEvaluatedKey; } while (lastEvaluatedKey); return result; }
注意:该方案会扫描全表,你需要为全表的读容量付费,即使最终过滤后仅返回几条结果,仅适合极低频率的查询场景,数据量超过1万条后不推荐使用。
内容的提问来源于stack exchange,提问作者roxx0r.munich
相关产品推荐
相关产品推荐

