首页 > 解决方案 > 使用扫描在使用 Nodejs 计算 DynamoDB 中的元素时出现问题

问题描述

我有一个 NodeJS 函数,它扫描 DynamoDB 中的表(没有主排序键)并返回列同步中为空的元素数。我的桌子:

var params = {
    AttributeDefinitions: [
        {
        AttributeName: "barname",
        AttributeType: "S"
        },
        {
        AttributeName: "timestamp",
        AttributeType: "S"
        }
    ],
    KeySchema: [
        {
        AttributeName: "barname",
        KeyType: "HASH"
        },
        {
        AttributeName: "timestamp",
        KeyType: "RANGE"
        }
    ],
    ProvisionedThroughput: {
        ReadCapacityUnits: 1,
        WriteCapacityUnits: 1
    },
    TableName: tableName
}; 

sync==false 时计数的函数

var dynamodb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
async function getCountNoSync(type){
    console.log(type)
    var params = {
        TableName: tableName,
        FilterExpression: 'sync = :sync and billing = :billing',
        ExpressionAttributeValues: {
            ':billing' : {S: type},
            ':sync' : {BOOL: false}
          },
    };
    
    var count = 0;
    await dynamodb.scan(params).promise()
        .then(function(data){
            count = data.Count;
        })
        .catch(function(err) {
            count = 0;
            console.log(err);
        });

    return count;
}

如果我的表中的元素很少(例如,少于 150 个),则该函数可以正常工作。如果元素数量较多,则计数变量始终为 0。看起来扫描并未找到所有元素。

有什么想法吗?此致

标签: node.jsamazon-dynamodb

解决方案


您没有找到属性的所有项目的原因sync == null是该scan操作仅读取表的一部分

正如文档所述:

如果扫描项目的总数超过最大数据集大小限制 1 MB,则扫描停止并将结果作为 LastEvaluatedKey 值返回给用户,以在后续操作中继续扫描。

因此,如果您的表有数百兆字节大,您需要scan()多次调用并提供LastEvaluatedKey读取表的下一个“页面”。这个过程也称为“分页”。

但这将花费大量时间,而且所需的时间会随着您的桌子大小而增加。这样做的正确方法是创建sync字段的索引,然后query()在该索引上执行。

您可以在 AWS 文档中阅读更多相关信息:

  1. 查询和扫描 DynamoDB 表
  2. scan() 的参考文档
  3. 对结果进行分页

推荐阅读