簡體   English   中英

無需掃描即可從表中獲取所有項目

[英]Get all items from a table without Scan

目前我有一個 function 使用 SCAN 選項從 DynamoDB 表中獲取所有項目。 這是一種昂貴的方法,我更喜歡使用 QUERY 選項。 但是查看文檔似乎沒有一種簡單的方法可以使用 QUERY 選項檢索所有項目 - 它需要某種條件。

例子

var params = {
    TableName : "Movies",
    KeyConditionExpression: "#yr = :yyyy",
    ExpressionAttributeNames:{
        "#yr": "year"
    },
    ExpressionAttributeValues: {
        ":yyyy": 1985
    }
};

docClient.query(params, function(err, data) {
    if (err) {
        console.error("Unable to query. Error:", JSON.stringify(err, null, 2));
    } else {
        console.log("Query succeeded.");
        data.Items.forEach(function(item) {
            console.log(" -", item.year + ": " + item.title);
        });
    }
});

預期的

var params = {
    TableName : "Movies"  
};

docClient.query(params, function(err, data) {
    if (err) {
        console.error("Unable to query. Error:", JSON.stringify(err, null, 2));
    } else {
        console.log("Query succeeded.");
        data.Items.forEach(function(item) {
            console.log(" -", item.year + ": " + item.title);
        });
    }
});

是否可以使用 QUERY 從表中檢索所有數據? 我想過使用 BEGINS_WITH 等,但所有主鍵都是不同的/隨機的,並且不以特定字符或短語開頭。

從技術上講,對 Amazon DynamoDB 表中所有項目的query將返回與scan返回的相同數量的數據,因此成本應該沒有差異。

scan操作通常會降低效率,因為它必須讀取整個表,然后過濾掉值以提供您想要的結果,本質上增加了從結果集中刪除數據的額外步驟。 如果您想在不過濾的情況下讀取整個表,則scanquery都必須檢索所有值,並且沒有額外的過濾步驟。

通過查詢進行的唯一方法是分別循環遍歷每個分區鍵。

我建議您查看圍繞您的查詢構建的二級索引,這將更有效: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SecondaryIndexes.html

如果您想獲取所有數據,您可以使用掃描所有數據,但我建議您通過限制和分頁獲取數據,因為如果您在 dynamodb 擁有數百萬數據,它會殺死大量 memory 資源。 這種獲取所有數據的方法

const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient({
    apiVersion: '2012-08-10',
    region: 'ap-southeast-1' // put your region
});

exports.handler = async (event, context, callback) => {
    const tableName = event.params.querystring.tablename; 
     let params = { 
         TableName: tableName
     };

     let scanResults = [];
     let items;

     do {
         items = await docClient.scan(params).promise();
         items.Items.forEach((item) => scanResults.push(item));
         params.ExclusiveStartKey = items.LastEvaluatedKey;
     } while (typeof items.LastEvaluatedKey != "undefined");

     callback(null, scanResults);
   
            
};

但是使用下面的方法,在獲取數據后,您需要將 LastEvaluatedKey 從前端發布到 params,您可以將其用作 ExclusiveStartKey。

const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient({
    apiVersion: '2012-08-10',
    region: 'ap-southeast-1' // put your region
});

exports.handler = async (event, context, callback) => {
    const tableName = event.params.querystring.tablename; 
    
    let pageSize = event.params.querystring.pagesize;
    let lastItem = event.params.querystring.lastItem;
        try {
              const params = {
                TableName: tableName,
                Limit: pageSize,
              };
              if (lastItem) {
                params.ExclusiveStartKey = { id: lastItem};
              }
              const response = await docClient.scan(params).promise();
              return {
                 items: response.Items,
                 lastItem: response.LastEvaluatedKey
              };
        
            } catch (error) {
              throw error;
            }
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM