使用AWS Lambda(Node.js)扫描DynamoDB无结果问题排查
问题分析与解决
你的扫描请求返回空Items但ScannedCount不为0,核心问题在于筛选条件的类型和值都与表中数据不匹配,再加上使用DocumentClient时错误地用了原生DynamoDB的类型标识格式。
具体问题点:
- 类型不匹配:表中
controlFunction是字符串类型(S),但你在ExpressionAttributeValues里指定了数字类型({ N: "5" }),DynamoDB会严格匹配类型,字符串和数字永远无法匹配。 - 值错误:你要筛选的是类似"Protect"的字符串,但代码里写的是数字5,完全不符合预期。
- DocumentClient的使用错误:
AWS.DynamoDB.DocumentClient是高层封装,不需要手动指定类型(比如N/S),直接传入JavaScript原生类型即可,它会自动转换为DynamoDB的类型格式。
修改后的代码:
const AWS = require("aws-sdk"); const dynamo = new AWS.DynamoDB.DocumentClient(); exports.handler = async (event, context) => { let controlInfo; let body; let statusCode = 200; const headers = { "Content-Type": "application/json" }; try { controlInfo = await dynamo .scan({ FilterExpression: "controlFunction = :cF", ExpressionAttributeValues: { ":cF": "Protect" // 直接传入字符串,无需类型标识 }, ProjectionExpression: "controlID", TableName: "testControls", }) .promise(); } catch (err) { statusCode = 400; controlInfo = err.message; } finally { //controlInfo = JSON.stringify(controlInfo); } body = { "Control Info" : controlInfo, "Threat Info" : "placeHolder" }; body = JSON.stringify(body); return { statusCode, body, headers }; };
额外说明:
- 如果需要动态传入筛选值,比如从event参数获取,直接传入对应的JavaScript类型即可(字符串就传字符串,数字就传数字)。
- 扫描操作会遍历整个表,数据量大时建议改用查询(Query)操作并创建对应的全局二级索引(GSI),以提升性能并减少消耗。
内容的提问来源于stack exchange,提问作者1HeavyHippo
相关产品推荐
相关产品推荐

