이전에는 event, context, callback 을 사용했지만 세번째 인자 callback은 더이상 잘 사용되지 않는다고 한다. 현재는 status code를 포함한 response 구조를 가진 객체를 return 하면 된다.
데이터를 가져오는 방법은 두가지가 있다.
특정 속성을 사용해 검색하고 싶은 경우 query를 사용하게 된다. 이때 검색에 사용하고자 하는 속성은 Index로 설정되어있어야 사용이 가능하다.
const ddbScanData = await ddb.scan(scanParams).promise();
const scanParams = {
TableName: "midibus-play-statistics",
ProjectionExpression: "#id",
ExpressionAttributeNames: {
"#id": "uuid",
},
};
function getUuid(data) {
const uuidArr = {};
data["Items"].forEach((e) => {
let tempUuid = e["uuid"]["S"];
if (!uuidArr[tempUuid]) uuidArr[tempUuid] = true;
});
return Object.keys(uuidArr);
}
id가 예약어이기 떄문에 ExpressionAttributeNames 로 예약어가 아닌 다른 변수명과 매핑시켰다.
ProjectionExpression 은 조회할 항목을 고르는 설정이다. 여기서 설정한 항목들만 db에서 스캔해온다.
async function getLatesData(uuids) {
const result = [];
uuids.forEach(async (uuid) => {
console.log("start query", uuid);
try {
const params = {
TableName: "midibus-play-statistics",
KeyConditionExpression: "#id = :v1",
ExpressionAttributeValues: {
":v1": { S: uuid },
},
ExpressionAttributeNames: {
"#id": "uuid",
},
Limit: 1,
ScanIndexForward: false,
};
console.log(params);
let latestData = await ddb.query(params).promise();
console.log(latestData);
result.push(latestData);
} catch (err) {
console.error(err);
}
});
return result;
}
uuid가 Hash Key, timestamp 가 Range Key로 설정되어있다. timestamp가 sorting key이기 때문에 Limit를 1로 두고 ScanIndexForward 값을 false로 지정해 내림차순 정렬을 하도록 했다.
여기서 오류가 계속 발생했다. 결과값이 계속해서 빈 배열로 나왔다. 끝내 찾아낸 이유는 비동기 처리가 잘못 되었던 것이었다. 쿼리가 잘못 된 줄 알고 계속해서 쿼리문 API만 다시 작성했는데 uuid 하나 넣어서 실행시켜보니 동작했다!😅…
함수가 내가 생각한 대로 동작하지 않았던 이유는 forEach 내부의 익명 함수는 동기 함수가 아니기 때문이었다. 때문에 비동기적으로 return result 문이 먼저 동작하게 되어 빈 배열이 반환되고 프로그램이 종료하게 된다.