SST+TypeScript实现S3对象按Metadata过滤查询遇阻求指导
问题解决指导
核心问题分析
getMetadata函数不兼容await:当前函数是回调式实现,await无法正确等待其执行完成,导致元数据获取异常。- 未正确提取成功结果的文件数据:原代码中
successfulFiles仅保留了Promise结果对象,没有访问value属性获取实际的文件和元数据信息,无法进行后续过滤。 - 缺少
createdBy过滤逻辑:未针对元数据中的createdBy字段(注意S3会将自定义元数据键转为小写,实际存储为createdby)进行过滤处理。 - 未获取查询参数中的用户名:没有从API请求中提取需要过滤的用户名条件。
修改后的完整代码
import { GetObjectOutput } from "aws-sdk/clients/s3"; import * as AWS from 'aws-sdk'; export async function main(event: any): Promise<any> { const s3 = new AWS.S3(); // 从API查询参数中获取要过滤的用户名 const targetUsername = event.queryStringParameters?.username; const params = { Bucket: 'uni-artifacts', }; try { console.log("Listing objects in bucket:", params.Bucket); const data = await s3.listObjectsV2(params).promise(); if (!data.Contents) { return { statusCode: 200, body: JSON.stringify({ message: "No files found in the bucket" }), }; } console.log("Number of objects found:", data.Contents.length); // 重构getMetadata为Promise版本,确保await能正常工作 const getMetadataPromise = async (s3: AWS.S3, key: string): Promise<GetObjectOutput["Metadata"]> => { const params = { Bucket: 'uni-artifacts', Key: key, }; const data = await s3.headObject(params).promise(); console.log("Got metadata for:", key); return data.Metadata; }; // 获取所有带元数据的文件 const files = await Promise.all( data.Contents.map(async (obj) => { try { const metadata = await getMetadataPromise(s3, obj.Key!); return { Key: obj.Key, Metadata: metadata, }; } catch (error) { console.error("Error getting metadata for", obj.Key, error); return { Key: obj.Key, Error: (error as Error).message }; } }) ); // 分离成功和失败的文件 const successfulFiles = files.filter(file => !file.Error); const failedFiles = files.filter(file => file.Error); // 根据用户名过滤成功文件(注意S3元数据键是小写的createdby) let filteredFiles = successfulFiles; if (targetUsername) { filteredFiles = successfulFiles.filter(file => file.Metadata?.createdby?.toLowerCase() === targetUsername.toLowerCase() ); } const responseBody = { statusCode: 200, body: JSON.stringify({ filteredFiles, failedFiles, totalFound: data.Contents.length, totalFiltered: filteredFiles.length }), }; return responseBody; } catch (error) { console.error("Error retrieving files:", error); return { statusCode: 500, body: JSON.stringify({ message: "Error retrieving files" }), }; } }
关键修改说明
- Promise化
getMetadata:将原回调式函数改为返回Promise的异步函数,确保await能正确等待元数据获取完成。 - 提取查询参数:从
event.queryStringParameters中获取要过滤的用户名,实现动态过滤。 - 处理元数据大小写:S3会将自定义元数据的键自动转为小写,所以过滤时匹配
createdby而非createdBy,同时做大小写不敏感匹配提升鲁棒性。 - 简化结果处理:用
Promise.all替代Promise.allSettled,直接在映射时处理错误,分离成功和失败文件更简洁。 - 添加过滤逻辑:根据目标用户名过滤成功获取元数据的文件,若没有传入用户名则返回全量成功文件。
内容的提问来源于stack exchange,提问作者Amjad Shubbar
相关产品推荐
相关产品推荐

