You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SST+TypeScript实现S3对象按Metadata过滤查询遇阻求指导

问题解决指导

核心问题分析

  1. getMetadata函数不兼容await:当前函数是回调式实现,await无法正确等待其执行完成,导致元数据获取异常。
  2. 未正确提取成功结果的文件数据:原代码中successfulFiles仅保留了Promise结果对象,没有访问value属性获取实际的文件和元数据信息,无法进行后续过滤。
  3. 缺少createdBy过滤逻辑:未针对元数据中的createdBy字段(注意S3会将自定义元数据键转为小写,实际存储为createdby)进行过滤处理。
  4. 未获取查询参数中的用户名:没有从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 16:45:02