0

我有一个表storedgames,其中包含 2092 个项目。

桌子

它还在该表上有一个索引,其中还列出了 2092 个项目。

用户索引

当我获取数据时,我使用索引来获取一个特定用户的项目。

const params = {
  TableName: "storedgames",
  IndexName: "user-index",
  KeyConditionExpression: "#usr = :usr",
  ExpressionAttributeNames: { "#usr": "user" },
  ExpressionAttributeValues: { ":usr": user }
};

const data = await new Promise((resolve, reject) => {
  docClient.query(params, (err, data) => {
    if (err) { reject(err); } else { resolve(data); }
  });
}).catch((err) => {
  console.error(err);
  return false;
});

但是,上面的代码不会返回所有项目。它只找到 42 个。对于今天的项目,只有 1 个命中。当我直接在 AWS 网页上查看时,我实际上找到了更多今天的项目。

表格中网页上的更多项目

即使我使用索引执行此操作,它也会找到更多记录。

网页上使用索引的更多项目

当我忽略一天的过滤时,我实际上找到了 130 多个项目,而当我忽略一天过滤器时,我的 javascript 代码仅返回 42 个项目。

130 对 42 项


所以我的问题是,当我以编程方式调用它时,为什么我的索引数据似乎不完整?

4

1 回答 1

0

这些记录实际上包含大量数据,并且每个查询可以获取的数据量似乎存在限制。

单个 Query 操作最多可以检索1 MB 的数据。此限制在将任何 FilterExpression 应用于结果之前应用。如果 LastEvaluatedKey 存在于响应中并且不为空,则必须对结果集进行分页(请参阅对结果进行分页)。

所以,我一种可能的解决方案是执行多次提取,直到你拥有整个集合。

const queryAllItems = (params, callback) => {
  let fullResult = { Items: [], Count: 0, ScannedCount: 0 };

  const queryExecute = (callback) => {
    docClient.query(params, (err, result) => {
      if (err) {
        callback(err);
        return;
      }

      const { Items, LastEvaluatedKey, Count, ScannedCount } = result;

      fullResult.Items = [...fullResult.Items, ...Items];
      fullResult.Count += Count;
      fullResult.ScannedCount += ScannedCount;

      if (!LastEvaluatedKey) {
        callback(null, fullResult);
        return;
      }

      params.ExclusiveStartKey = LastEvaluatedKey;
      queryExecute(callback);
    });
  }

  queryExecute(callback);
}

不幸的是,这不是一个完整的解决方案。在我的情况下,仅查询 130 个项目(需要 4 次实际提取)大约需要 15 秒。

于 2019-08-16T15:31:53.627 回答