همه نتایج را از DynamoDB Queries به راحتی دریافت کنید!

یک پرس و جو DynamoDB فقط می تواند 1 مگابایت نتیجه را برگرداند. بنابراین، چگونه می توانید تمام نتایج یک پرس و جو را اگر بزرگتر از آن باشد، دریافت کنید؟ دو راه وجود دارد: راه ساده و راه جالب.
صفحه بندی پرس و جو DynamoDB چگونه کار می کند
قبل از اینکه شروع به دریافت تعداد دیوانه کننده رکورد کنیم، بیایید پشتیبان گیری کنیم و در مورد نحوه کار صفحه بندی در DynamoDB صحبت کنیم. وقتی یک پرس و جو دارای رکوردهای بیشتری از آن چیزی است که می تواند برگرداند، یا به این دلیل که شما آن را تنظیم کرده اید Limit
دارایی یا بیشتر از آن وجود دارد 1MB
از نتایج، دینامو تمام رکوردهایی را که می تواند به همراه یک دارایی برمی گرداند LastEvaluatedKey
.
تا زمانی که LastEvaluatedKey
ویژگی در نتایج پرس و جو تنظیم شده است، به این معنی که شما هنوز نتایجی برای دریافت دارید. اگر می خواهید آن نتایج را دریافت کنید، پارامترهای پرس و جو اصلی را به روز کنید تا ExclusiveStartKey
تنظیم شده است LastEvaluatedKey
و دوباره کوئری را اجرا کنید.
راه ساده
راه ساده واضح ترین است: از یک حلقه do استفاده کنید. شرایط را بررسی کنید تا ببینید آیا ExclusiveStartKey
تنظیم شد. اگر تنظیم شده باشد، می دانید که رکوردهای بیشتری وجود دارد و باید دوباره کوئری را اجرا کنید.
export const getAllResults = async <T>(
db: AWS.DynamoDB.DocumentClient,
query: AWS.DynamoDB.DocumentClient.QueryInput
): Promise<Array<T>> => {
const result = [] as Array<T>;
console.info(`Querying Dynamo`, query.ExpressionAttributeValues);
let queryResult: AWS.DynamoDB.DocumentClient.QueryOutput;
do {
queryResult = await db.query(query).promise();
console.info(`Query Result`, queryResult);
query.ExclusiveStartKey = queryResult?.LastEvaluatedKey;
queryResult.Items?.forEach(item => result.push(item as T));
} while (query.ExclusiveStartKey);
console.info(
`Found ${result.length} results for ${query.KeyConditionExpression}`,
inspect(query.ExpressionAttributeValues)
);
return result;
};
استفاده از Async Generator
مشکل یک do-loop این است که همه نتایج در حافظه ذخیره می شوند. اگر رکوردهای زیادی دارید ممکن است مشکل ساز باشد. روش جالبتر برای انجام این کار با یک ژنراتور async node.js است.
ژنراتور async نوع خاصی از تکرار کننده است که به شما امکان می دهد yield
مقادیری که بازیابی می شوند. نمونه کد زیر ژنراتور Async DynamoDB را ایجاد می کند.
export async function* getAllResults<T>(
db: AWS.DynamoDB.DocumentClient,
query: AWS.DynamoDB.DocumentClient.QueryInput
) {
console.info(`Querying Dynamo`, query.ExpressionAttributeValues);
let queryResult: AWS.DynamoDB.DocumentClient.QueryOutput;
do {
queryResult = await db.query(query).promise();
console.info(`Query Result`, queryResult);
query.ExclusiveStartKey = queryResult?.LastEvaluatedKey;
if(queryResult.Items) {
yield* queryResult.Items;
}
} while (query.ExclusiveStartKey);
};
فراخوانی آن
اکنون که ژنراتور ایجاد شده است، می توانید آن را با استفاده از نحو نامناسب زیر فراخوانی کنید.
for await (const record of getAllResults(db, query)) {
console.info(record);
}
نتیجه
برای نتیجه گیری، اگر یک Query DynamoDB دارید که بیش از 1 مگابایت نتیجه را برمی گرداند، راه ساده برای مدیریت صفحه بندی استفاده از حلقه do-loop است و راه کارآمدتر استفاده از یک ژنراتور async است.