繁体   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