use*_*811 4 pagination amazon-web-services node.js amazon-dynamodb
我已经阅读了有关分页的AWS文档:http : //docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html#ScanQueryLimit
正如他们的文档指定的那样:
在响应中,DynamoDB返回在Limit值范围内的所有匹配结果。例如,如果您发出“限制”值为6且没有过滤表达式的查询或扫描请求,则DynamoDB会返回表中与请求中指定的关键条件匹配的前六个项目(或仅返回前六个项目)。在没有过滤器的情况下扫描)
这意味着,假设我有一个Questions带有名为的属性的调用表(该属性difficulty可以采用从0到的任何数值2),我可能会遇到以下难题:
GET /questions?difficulty=0&limit=3 3给DynamoDB查询,该查询可能返回0项目,因为集合中的前3个可能不是difficulty == 0questions符合该条件的查询,而不知道我可能会返回重复项然后如何根据查询正确分页?在具有正确偏移量的情况下,可以获得与我要求的结果一样多的结果
Ros*_*wal 21
使用异步/等待。
const getAllData = async (params) => {
console.log("Querying Table");
let data = await docClient.query(params).promise();
if(data['Items'].length > 0) {
allData = [...allData, ...data['Items']];
}
if (data.LastEvaluatedKey) {
params.ExclusiveStartKey = data.LastEvaluatedKey;
return await getAllData(params);
} else {
return data;
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用全局变量allData来收集所有数据。
调用此函数包含在 try-catch 中
try {
await getAllData(params);
console.log("Processing Completed");
// console.log(allData);
} catch(error) {
console.log(error);
}
Run Code Online (Sandbox Code Playgroud)
我在Lambda 中使用它,它工作正常。
这里的文章真的对我有帮助和指导。谢谢。
Ant*_*ton 11
我希望你明白了。所以以防万一其他人可能会发现它有用。AWS 有 QueryPaginator/ScanPaginator ,如下所示:
const paginator = new QueryPaginator(dynamoDb, queryInput);
for await (const page of paginator) {
// do something with the first page of results
break
}
Run Code Online (Sandbox Code Playgroud)
有关更多详细信息,请访问https://github.com/awslabs/dynamodb-data-mapper-js/tree/master/packages/dynamodb-query-iterator
paginateXXXX2022-05-19:对于 AWS SDK v3,请参阅此博客文章https://aws.amazon.com/blogs/developer/pagination-using-async-iterators-in-modular-aws-sdk-for-的使用方法javascript/
避免使用递归来防止调用堆栈溢出。扩展@Roshan Khandelwal 方法的迭代解决方案:
const getAllData = async (params) => {
const _getAllData = async (params, startKey) => {
if (startKey) {
params.ExclusiveStartKey = startKey
}
return this.documentClient.query(params).promise()
}
let lastEvaluatedKey = null
let rows = []
do {
const result = await _getAllData(params, lastEvaluatedKey)
rows = rows.concat(result.Items)
lastEvaluatedKey = result.LastEvaluatedKey
} while (lastEvaluatedKey)
return rows
}
Run Code Online (Sandbox Code Playgroud)
这是一个如何在Node.js中从DynamoDB scan(也可以很容易地对其进行修改query)的分页结果集中进行迭代的示例。
您可以保存LastEvaluatedKey状态服务器端,然后将标识符传递回您的客户端,该标识符将与下一个请求一起发送,并且服务器将在下一个请求中将该值传递ExclusiveStartKey给DynamoDB。
const AWS = require('aws-sdk');
AWS.config.logger = console;
const dynamodb = new AWS.DynamoDB({ apiVersion: '2012-08-10' });
let val = 'some value';
let params = {
TableName: "MyTable",
ExpressionAttributeValues: {
':val': {
S: val,
},
},
Limit: 1000,
FilterExpression: 'MyAttribute = :val',
// ExclusiveStartKey: thisUsersScans[someRequestParamScanID]
};
dynamodb.scan(scanParams, function scanUntilDone(err, data) {
if (err) {
console.log(err, err.stack);
} else {
// do something with data
if (data.LastEvaluatedKey) {
params.ExclusiveStartKey = data.LastEvaluatedKey;
dynamodb.scan(params, scanUntilDone);
} else {
// all results scanned. done!
someCallback();
}
}
});
Run Code Online (Sandbox Code Playgroud)
查询和扫描操作返回LastEvaluatedKey其响应。如果没有并发插入,只要您迭代调用 Query/Scan 并将 ExclusiveStartKey 设置为前一个调用的 LastEvaluatedKey,您就不会错过项目,也不会多次遇到项目。
| 归档时间: |
|
| 查看次数: |
9772 次 |
| 最近记录: |