如何在不使用Node-js扫描的情况下从Dynamo-Db读取单个列?

时间:2018-02-12 17:53:31

标签: node.js amazon-dynamodb aws-sdk-nodejs

我的Dynamo Db中有450万条记录。

我想以批处理方式读取每条记录的ID。

我期待像我们在Mongo Db中读取的偏移和限制之类的东西。

Node-JS中是否有任何没有扫描方法的建议。

我已经做了足够的研究,我只能找到扫描方法来缓冲Dynamo Db的完整记录,并开始扫描记录,这在性能基础上无效。

请给我建议。

2 个答案:

答案 0 :(得分:3)

从我的观点来看,扫描没问题,因为(根据Scan doc):

  •   

    DynamoDB将扫描操作的结果分页

  •   

    您可以使用ProjectionExpression参数,以便Scan仅返回部分属性,而不是所有属性

页面的默认大小为1MB,但您也可以使用Limit参数指定每页的最大项目数。

所以它只是基本的分页,与MongoDB对offsetlimit的处理方式相同。

Here是有关如何使用node.js SDK执行扫描的文档中的示例。

现在,如果您想以批量方式获取所有ID,可以使用Promise包装整个内容,并在没有LastEvaluatedKey的情况下解决。

下面是你可以做的伪代码:

const performScan = () => new Promise((resolve, reject) => {
    const docClient = new AWS.DynamoDB.DocumentClient();
    let params = {
        TableName:"YOUR_TABLE_NAME",
        ProjectionExpression: "id",
        Limit: 100 // only if you want something else that the default 1MB. 100 means 100 items
    };
    let items = [];

    var scanExecute = cb => {
        docClient.scan(params, (err,result) => {
            if(err) return reject(err);

            items = items.concat(result.Items);
            if(result.LastEvaluatedKey) {
                params.ExclusiveStartKey = result.LastEvaluatedKey;
                return scanExecute();
            } else {
                return err
                    ? reject(err)
                    : resolve(items);
            }
        });
    };
    scanExecute();
});

performScan().then(items => {
    // deal with it
});

答案 1 :(得分:2)

有关DynamoDB的第一件事就是它是一个支持二级索引的键值存储。

如果应用程序经常必须在不使用索引(主要或次要)的情况下迭代整个数据集,那么DynamoDB是一个糟糕的选择,因为唯一的方法是使用Scan API。

DynamoDB表扫描(我能想到的一些事情)

  1. 贵(我的意思是$$$)
  2. 大数据集的速度慢
  3. 可能会耗尽预配置的吞吐量
  4. 如果您知道DynamoDB中所有项目的主键(某些外部知识,如primary是自动递增的值,在另一个DB等中引用),那么您可以使用BatchGetItemQuery

    因此,如果它是一次性的事情,那么Scan是您唯一的选择,您应该考虑重构您的应用程序以删除此方案。