最新消息: 电脑我帮您提供丰富的电脑知识,编程学习,软件下载,win7系统下载。

AWS Lambda NodeJS:使用可选的过滤器属性进行扫描

IT培训 admin 4浏览 0评论

AWS Lambda NodeJS:使用可选的过滤器属性进行扫描

我构建了一个AWS Lambda,用于扫描和过滤我的DynamoDB并返回到我的AWS API。因此,我有三个可能的搜索参数(itemname,author和type),而我不知道在查询中使用了哪些参数。起初,我实现了一个版本,其中所有搜索参数都是硬编码的。结果,如果不是所有定义的搜索参数,我都会收到错误。最后,我重新编写代码,根据输入的搜索参数构建单独的扫描参数。

代码工作正常,但我认为这个问题有更好的实现,也许你可以给我一些改进建议。否则,这将帮助那些面临相同问题的人使用他们的可选搜索参数。

var AWS = require('aws-sdk');
var docClient = new AWS.DynamoDB.DocumentClient();

//This is the Lambda function
exports.handler = function(event, context, callback) 
{
//In case we query without query attributes
if(!event.hasOwnProperty("queryStringParameters"))
        {
            console.log("NO queryStringParameters FOUND");
            var emptyparams = 
                {  
                    TableName: "blackboard-items",
                };
            docClient.scan(emptyparams, onScan);
            return;
        }
        
//we want to tailor this attributes for the params for docClient.scan(params, onScan); 
var queryParam = event["queryStringParameters"];
var filterexpression = "";
var expressionAttributeNames = {}; //Instantiate
var expressionAttributeValues = {};
console.log("QUERY PARAMETERS: " + JSON.stringify(queryParam));
    
//Do we look for an author?
if(queryParam.hasOwnProperty("author"))
    {
        console.log("FOUND AUTHOR");
        filterexpression += "contains(#author, :author)"; //Collect scan params
        expressionAttributeNames['#author'] = 'author';
        expressionAttributeValues[':author'] = event["queryStringParameters"]["author"];
    }
    
//Do we look for an itemname?
if(queryParam.hasOwnProperty("itemname"))
    {
    console.log("FOUND ITEMNAME");
    if(filterexpression !== "")
        filterexpression += " AND contains(#itemname, :itemname)";
    else
        filterexpression += "contains(#itemname, :itemname)";
        
    expressionAttributeNames['#itemname'] = 'itemname';
    expressionAttributeValues[':itemname'] = queryParam["itemname"];    
    }
    
//Do we look for a type?
if(queryParam.hasOwnProperty("type"))
    {
    console.log("FOUND TYPE");
    if(filterexpression !== "")
        filterexpression += " AND #type = :type";
    else
        filterexpression += "#type = :type";
        
    expressionAttributeNames['#type'] = 'type';
    expressionAttributeValues[':type'] = event["queryStringParameters"]["type"]; 
    }
  
//Build params based on the tailored parts
var params = 
    {  
        TableName: "blackboard-items",
        FilterExpression: filterexpression,
        ExpressionAttributeNames: expressionAttributeNames,
        ExpressionAttributeValues: expressionAttributeValues,
    };
  
//Use tailored params for scan()
docClient.scan(params, onScan);
var count = 0;

function onScan(err, data)
    {
       if (err) 
        {
        console.error("Unable to scan the table. Error JSON:", JSON.stringify(err, null, 2));
        } 
        else 
        {        
        console.log("Scan succeeded.");
        data.Items.forEach(function(itemdata) 
            {
               console.log("Item :", ++count,JSON.stringify(itemdata));
            });

            // continue scanning if we have more items
            if (typeof data.LastEvaluatedKey != "undefined") 
            {
                console.log("Scanning for more...");
                params.ExclusiveStartKey = data.LastEvaluatedKey;
                docClient.scan(params, onScan);
            }
        }
        
        
    var response = 
    {
    "isBase64Encoded": false,
    "statusCode": "200",
    "headers": {  },
    "body": JSON.stringify(data.Items)
    };
 
    callback(null, response);
        
    }
 };
回答如下:

DynamoDB的查询功能非常有限,因此,您应该不惜一切代价购买avoid scan。每次扫描操作都会为其读取的每个项目消耗RCU。如果您的桌子有很多项目,它可以很快耗尽您的RCU。

如果您想通过这3个属性进行查询,那么DynamoDB可能不是您用例的最佳数据库。如果您可以一次将查询缩小到1个属性,则可以使用Global Secondary Indexes。这样您就可以根据作者或类型进行查询。您可以看到this回答如何在DynamoDB中查询GSI

AWS Lambda NodeJS:使用可选的过滤器属性进行扫描

我构建了一个AWS Lambda,用于扫描和过滤我的DynamoDB并返回到我的AWS API。因此,我有三个可能的搜索参数(itemname,author和type),而我不知道在查询中使用了哪些参数。起初,我实现了一个版本,其中所有搜索参数都是硬编码的。结果,如果不是所有定义的搜索参数,我都会收到错误。最后,我重新编写代码,根据输入的搜索参数构建单独的扫描参数。

代码工作正常,但我认为这个问题有更好的实现,也许你可以给我一些改进建议。否则,这将帮助那些面临相同问题的人使用他们的可选搜索参数。

var AWS = require('aws-sdk');
var docClient = new AWS.DynamoDB.DocumentClient();

//This is the Lambda function
exports.handler = function(event, context, callback) 
{
//In case we query without query attributes
if(!event.hasOwnProperty("queryStringParameters"))
        {
            console.log("NO queryStringParameters FOUND");
            var emptyparams = 
                {  
                    TableName: "blackboard-items",
                };
            docClient.scan(emptyparams, onScan);
            return;
        }
        
//we want to tailor this attributes for the params for docClient.scan(params, onScan); 
var queryParam = event["queryStringParameters"];
var filterexpression = "";
var expressionAttributeNames = {}; //Instantiate
var expressionAttributeValues = {};
console.log("QUERY PARAMETERS: " + JSON.stringify(queryParam));
    
//Do we look for an author?
if(queryParam.hasOwnProperty("author"))
    {
        console.log("FOUND AUTHOR");
        filterexpression += "contains(#author, :author)"; //Collect scan params
        expressionAttributeNames['#author'] = 'author';
        expressionAttributeValues[':author'] = event["queryStringParameters"]["author"];
    }
    
//Do we look for an itemname?
if(queryParam.hasOwnProperty("itemname"))
    {
    console.log("FOUND ITEMNAME");
    if(filterexpression !== "")
        filterexpression += " AND contains(#itemname, :itemname)";
    else
        filterexpression += "contains(#itemname, :itemname)";
        
    expressionAttributeNames['#itemname'] = 'itemname';
    expressionAttributeValues[':itemname'] = queryParam["itemname"];    
    }
    
//Do we look for a type?
if(queryParam.hasOwnProperty("type"))
    {
    console.log("FOUND TYPE");
    if(filterexpression !== "")
        filterexpression += " AND #type = :type";
    else
        filterexpression += "#type = :type";
        
    expressionAttributeNames['#type'] = 'type';
    expressionAttributeValues[':type'] = event["queryStringParameters"]["type"]; 
    }
  
//Build params based on the tailored parts
var params = 
    {  
        TableName: "blackboard-items",
        FilterExpression: filterexpression,
        ExpressionAttributeNames: expressionAttributeNames,
        ExpressionAttributeValues: expressionAttributeValues,
    };
  
//Use tailored params for scan()
docClient.scan(params, onScan);
var count = 0;

function onScan(err, data)
    {
       if (err) 
        {
        console.error("Unable to scan the table. Error JSON:", JSON.stringify(err, null, 2));
        } 
        else 
        {        
        console.log("Scan succeeded.");
        data.Items.forEach(function(itemdata) 
            {
               console.log("Item :", ++count,JSON.stringify(itemdata));
            });

            // continue scanning if we have more items
            if (typeof data.LastEvaluatedKey != "undefined") 
            {
                console.log("Scanning for more...");
                params.ExclusiveStartKey = data.LastEvaluatedKey;
                docClient.scan(params, onScan);
            }
        }
        
        
    var response = 
    {
    "isBase64Encoded": false,
    "statusCode": "200",
    "headers": {  },
    "body": JSON.stringify(data.Items)
    };
 
    callback(null, response);
        
    }
 };
回答如下:

DynamoDB的查询功能非常有限,因此,您应该不惜一切代价购买avoid scan。每次扫描操作都会为其读取的每个项目消耗RCU。如果您的桌子有很多项目,它可以很快耗尽您的RCU。

如果您想通过这3个属性进行查询,那么DynamoDB可能不是您用例的最佳数据库。如果您可以一次将查询缩小到1个属性,则可以使用Global Secondary Indexes。这样您就可以根据作者或类型进行查询。您可以看到this回答如何在DynamoDB中查询GSI

发布评论

评论列表 (0)

  1. 暂无评论