在一个AWS Lambda函数中组合多个查询

时间:2018-11-17 07:54:55

标签: node.js aws-lambda amazon-dynamodb

在DynamoDB表中,我紧随UserB(myFriends ..)之后有userA(MyUser)的项目

Primary-------|---- Srotkey---|---FriendID---|
 Myid.....       Friend-01        22223333

在同一表格中,我也有用户个人资料。.

Primary-------|---- Srotkey---|----Name----|
 Myid.....       Friend-01
 22223333          Profile         Rose    

现在,我想要一个功能来返回朋友的个人资料。 我想我的lambda“ getFriendProfile”函数应该执行两个查询,在第一个查询中获取我要关注的人的ID,然后在第二个查询中使用该结果获取她的个人资料。

我知道如何单独获得这些结果,但是我不知道如何将它们组合起来并将它们都整合到一个函数中。

第一个查询(getPeopleIFollow)

module.exports.handler = async (event, context, callback) => {

    const _userID = event.userID;

    var params = {
    TableName: "mytableName",
    ProjectionExpression: "FriendID",
    KeyConditionExpression: "#tp = :userId and begins_with(#sk, :skv)",
    ExpressionAttributeNames: {
      "#tp": "userId",
      "#sk": "Sortkey",
    },
    ExpressionAttributeValues: {
      ":userId": { "S": _userID },
      ":skv": { "S": "Friend" },

    }

    }
var Friend_ID;

try {

let data = await dynamodb.query(params).promise();

data.Items.map(
  (dataField) => {

  Friend_ID = dataField.FriendID.S,


  }

);

   callback(null, Friend_ID );

  }
  catch (error) {
    console.log(error);

    callback(error);
  }

};

我的其他功能看起来很像第一个.. getProfileNames ..

module.exports.handler = async (event, context, callback) => {

    const _userID = event.myfriendID;

    var params = {
    TableName: "mytableName",
    ProjectionExpression: "Name",
    KeyConditionExpression: "#tp = :userId and begins_with(#sk, :skv)",
    ExpressionAttributeNames: {
      "#tp": "userId",
      "#sk": "Sortkey",
    },
    ExpressionAttributeValues: {
      ":userId": { "S": _userID },
      ":skv": { "S": "Profile" },

    }

    }
try {

let data = await dynamodb.query(params).promise();

const items = data.Items.map(
  (dataField) => {

      return {
        friend_name: dataField.Name.S,

    }

  }


);

   callback(null, items );

  }
  catch (error) {
    console.log(error);

    callback(error);
  }

};

1 个答案:

答案 0 :(得分:1)

保持功能独立于每个Lambda实际上是一种组织代码的好方法。因此,您可以按原样保留代码,并为每个getPeopleIFollow结果invoke indexes lambda。

我认为从您的处理程序中尽可能抽象出来也是一个好主意,这样可以很容易地从高层次进行跟踪。因此,以下示例假定您的代码在其他返回诺言的函数中。

(未经测试的代码)

module.exports.handler = async (event, context, callback) => {
    const _userID = event.userID;
    try {
        const userFriends = await getUserFriends(userId);
        const friendProfiles = await getFriendProfiles(userFriends);
        callback(null, friendProfiles );
    } catch (error) {
        console.log(error);
        callback(error);
    }
}

lambda调用发生在getFriendProfiles中,后者使用Promise.all为每个单独的friendProfile请求调用lambda。

(未经测试的代码)

function getFriendProfiles(userFriends){
    return Promise.all(userFriends.map(userFriend => {
        const params = {
            ClientContext: "MyApp", 
            FunctionName: "MyFunction", 
            InvocationType: "RequestResponse", // important, you choose this so you get a response otherwise (eg if you choose the 'Event' InvocationType) I think the promise will resolve once the invocation is successful
            LogType: "Tail", 
            Payload: JSON.stringify({ myfriendID: userFriend }), // I think this is right, I usually use pathParameters or body for my payloads
            Qualifier: "1"
        };
        lambda.invoke(params).promise();
    });
}

说了这么多-大量的数据库查询表明,也许这种DynamoDb模式不是最有效的。在这种情况下,TableUser可能会有所帮助,甚至使用RDS而不是dynamodb。