【问题标题】:How to read an individual column from Dynamo-Db without using Scan in Node-js?如何在不使用 Node-js 中的 Scan 的情况下从 Dynamo-Db 中读取单个列?
【发布时间】:2018-07-22 23:35:20
【问题描述】:

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

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

我期待诸如偏移和限制之类的东西,例如我们在 Mongo Db 中的阅读方式。

Node-JS 中是否有没有scan方法的建议。

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

请给我建议。

【问题讨论】:

  • 如果您为您的表提供架构,我们也许可以找出查询而不是扫描。
  • 因为你想要整个表,Scan 是一个有效的选项。 Scan 性能不佳的唯一原因是它会扫描整个表,这正是我们想要的。
  • 您也可以使用 AWS DataPipeline 将数据传输到 S3 或 RedShift

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


【解决方案1】:

在我看来,扫描没有问题,因为(根据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
});

【讨论】:

【解决方案2】:

首先要了解 DynamoDB,它是一个支持二级索引的键值存储。

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 2016-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    • 2015-12-11
    • 1970-01-01
    相关资源
    最近更新 更多