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

How to read an individual column from Dynamo-Db without using Scan in Node-js?

我的 Dynamo 数据库中有 450 万条记录。

我想分批读取每条记录的id。

我期待像偏移量和限制这样的东西,比如我们如何读取 Mongo Db。

在Node-JS中有没有没有扫描方法的方法建议。

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

请给我建议。

在我看来,扫描没有问题,因为(根据 Scan doc):

  • DynamoDB paginates the results from Scan operations

  • You can use the ProjectionExpression parameter so that Scan only returns some of the attributes, rather than all of them

页面的默认大小为 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
});

关于 DynamoDB,首先要了解的是它是一个 Key-Value 支持二级索引的存储。

如果应用程序经常需要在不使用索引(主索引或辅助索引)的情况下遍历整个数据集,那么 DynamoDB 是一个糟糕的选择,因为唯一的方法是使用 Scan API.

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

  1. 贵(我是说$$$)
  2. 大数据集速度慢
  3. 可能会用完预配的吞吐量

如果您知道 DynamoDB 中所有项目的主键(一些外部知识如主键是一个自动递增的值,在另一个数据库中被引用等)那么您可以使用 BatchGetItemQuery.

因此,如果这是一次性的事情,那么 Scan 是您唯一的选择,否则您应该考虑重构您的应用程序以消除这种情况。