【问题标题】:Inconsistent results with query/scan DynamoDB - NodeJS查询/扫描 DynamoDB 的结果不一致 - NodeJS
【发布时间】:2017-02-08 23:50:18
【问题描述】:

我有一个如下所示的 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);
    }
});

它似乎正在工作,但我得到的结果比预期的要少。相同的代码在较小的表上也能正常工作。

与“扫描”类似的结果。

我错过了什么?

【问题讨论】:

    标签: node.js amazon-dynamodb


    【解决方案1】:

    根据每条记录的大小,检索到的记录数会有所变化,因为 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);
        }
      });
    

    【讨论】:

      【解决方案2】:

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

      你需要像下面这样改变你的实现

      第一步:调用DyanmoDB表,会返回第1个1mb的数据,随之返回"Next Evaluated Key"

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

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

      以下是参考资料:

      About query limits

      Blog on how to implement this code

      希望有帮助

      【讨论】:

        猜你喜欢
        • 2020-07-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-05
        相关资源
        最近更新 更多