繁体   English   中英

查询/扫描 DynamoDB - NodeJS 的结果不一致

[英]Inconsistent results with query/scan DynamoDB - NodeJS

我有一个看起来像这样的 DynamoDB 表:

在此处输入图像描述

(有大约 1500000 个像这样的条目具有不同的时间戳)

我有 2 个 GSI:

在此处输入图像描述

我正在尝试检索给定日期表中的所有行。

这就是我的代码(NodeJS)的样子:

var AWS = require("aws-sdk");

AWS.config.update({accessKeyId: "", secretAccessKey: ""});
AWS.config.update({region: 'us-east-1'});

var docClient = new AWS.DynamoDB.DocumentClient();

var params = {
    TableName: "QfGamingTransactionsProd",
    IndexName: 'Result-RedeemedAt-index',
    KeyConditionExpression: "#rs = :result and begins_with (#rat, :Rat)",
    ExpressionAttributeNames: {
        "#rs": "Result",
        "#rat": "RedeemedAt"
    },
    ExpressionAttributeValues: {
        ":result": "SUCCESS",
        ":Rat": "2016-10-20"
    }
};

docClient.query(params, function (err, data) {
    if (err) {
        console.error("Unable to query. Error:", JSON.stringify(err, null, 2));
    } else {
        console.log("\nQuery succeeded. \n");
        console.log("- Total", data.Count);
    }
});

它似乎有效,但我得到的结果(方式)比预期的要少。 同样的代码在较小的表上运行良好。

与“扫描”类似的结果。

我错过了什么?

根据每条记录的大小,检索到的记录数会发生变化,因为 DynamoDB 有查询大小限制(1MB)。

在 DynamoDB 中,一个查询只会返回 1MB 的数据。 但是我们可以对结果进行分页。 它可能会解决您的问题。 如果未完全检索满足该查询的数据,则查询返回的数据将包含“LastEvaluatedKey”。 所以我们必须将“LastEvaluatedKey”设置为“ExclusiveStartKey”。 然后查询将检索剩余的数据。 通过递归地按照这个方法,我们将得到完整的数据。

var data = [];
async.until(function () {
  return scanComplete;
},
  function (callback) {
    docClient.query(params, function (err, result) {
      if (err) {
        console.log(err);
      } else {
        data.push(result.Items);
        if (typeof (result.LastEvaluatedKey) === 'undefined') {
          scanComplete = true;
          //fully retrieved
        } else {
          params.ExclusiveStartKey = result.LastEvaluatedKey;
        }
        if (!scanComplete) {
        }
      }
      callback(err);
    });
  },
  // this runs when the loop is complete or returns an error
  function (err) {
    if (err) {
      console.log('error in processing scan ');
      console.log(err);
      reject(err);
    } else {
      resolve(data);
    }
  });

这是因为默认情况下 DynamoDB 一次只会返回 1mb 的数据,但是有一种方法可以解决这个问题。

您需要像下面这样更改您的实现

第 1 步:调用 DyanmoDB 表,它将返回第一个 1mb 的数据,并返回"Next Evaluated Key"

第 2 步:再次调用 Dynamodb 表,但这次您在"Exclusive Start key"中传递"Next Evaluated Key"以获取新的数据集

3 步:检查"Next Evaluated Key"是否仍然可用,然后重复第 2 步,否则您将获得该密钥的所有数据

以下是参考资料:

关于查询限制

关于如何实现此代码的博客

希望有帮助

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM