برنامه نویسی

همه نتایج را از 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 است.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا