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

SuiteScript Map/Reduce:Reduce到Summarize阶段无Context值传递求助

SuiteScript Map/Reduce 问题:Summarize阶段无法获取Reduce传递的数据

问题描述

我是SuiteScript新手,学习时遇到一个问题:Reduce函数里的日志能正常显示预期值,但Summarize函数无法获取Reduce阶段传递的context值,日志只显示{"type":"mapreduce.Summary","dateCreated":"2023-08-29T17:02:27.014Z","seconds":9,"usage":190,"concurrency":5,"yields":0},导致报错。我需要把Reduce阶段的fileList数据传递到Summarize阶段处理。

原始代码

function reduce(context) {
    try {
        var transactions = JSON.parse(context.values[0]); // 解析getInputData加载的文件内容

        log.debug('Reduce Context', transactions); // 这里日志能正常输出预期值

        if (transactions && transactions.length > 0) {
            // 遍历交易数组
            transactions.forEach(function (transaction) {
                /** .... 处理transaction对象的其他逻辑
                ......... 创建并保存日记账
                */
                // 构建文件列表并写入需要传递的上下文
                context.write({
                    key: "fileList",
                    value: {
                        fieldId: transaction.fileId,
                        duplicate: transaction.duplicate,
                        failed: transaction.failed
                    }
                });
            });
        }
    } catch (e) {
        log.error('Reduce Error', 'Error in Reduce function => ' + e.name + ' : ' + e.message);
    }
}

function summarize(context) {
    try {
        log.debug('Summarized Context', context); // 日志仅显示Summary对象,没有预期的数据

        fileList = JSON.parse(context.values[0]); // 尝试解析Reduce阶段传递的值
        if (fileList && fileList.length > 0) {
            // 遍历文件列表,将文件移动到对应文件夹
            fileList.forEach(function (file) {
                var fileObj = file.load({
                    id: file.fileID
                });
                if (file.duplicate === "Y") {
                    fileObj.folder = DUPLICATE_FILE_FOLDER_ID; // 从待处理文件夹移到重复文件夹
                } else if (file.failed === "Y") {
                    fileObj.folder = FAILED_FILE_FOLDER_ID; // 从待处理文件夹移到失败文件夹
                } else {
                    fileObj.folder = PROCESSED_FILE_FOLDER_ID; // 从待处理文件夹移到已处理文件夹
                }

                fileObj.save();
            });
        }
    } catch (err) {
        log.audit('File Moving Error', err.name + ' : ' + err.message);
    }
}

问题分析

  1. Summarize阶段数据获取方式错误:Summarize的context是Summary对象,无法直接通过context.values[0]获取Reduce输出的数据,必须通过context.output.iterator迭代器遍历Reduce阶段的输出结果。
  2. Reduce阶段写入数据类型错误:SuiteScript Map/Reduce中,context.write的value必须是字符串类型,直接传入对象会导致序列化异常,无法正确传递到Summarize阶段。
  3. 变量未声明:Summarize中的fileList未用var/let/const声明,属于全局变量,可能引发意外问题。
  4. 字段名拼写不一致:代码中存在fileId和fileID的拼写差异,会导致无法正确获取文件ID。

解决方案

修正后的Reduce函数

function reduce(context) {
    try {
        var transactions = JSON.parse(context.values[0]);

        log.debug('Reduce Context', transactions);

        if (transactions && transactions.length > 0) {
            transactions.forEach(function (transaction) {
                /** .... 其他处理逻辑 */
                // 将对象转为JSON字符串后写入,确保数据能正确传递
                context.write({
                    key: "fileList",
                    value: JSON.stringify({
                        fileId: transaction.fileId, // 统一字段名,避免拼写错误
                        duplicate: transaction.duplicate,
                        failed: transaction.failed
                    })
                });
            });
        }
    } catch (e) {
        log.error('Reduce Error', 'Error in Reduce function => ' + e.name + ' : ' + e.message);
    }
}

修正后的Summarize函数

function summarize(context) {
    try {
        var fileList = [];
        var iterator = context.output.iterator();
        var result;

        // 遍历所有Reduce输出的键值对,收集数据到数组
        while ((result = iterator.next()) != null) {
            fileList.push(JSON.parse(result.value));
        }

        log.debug('Collected File List', fileList);

        if (fileList.length > 0) {
            fileList.forEach(function (file) {
                var fileObj = file.load({
                    id: file.fileId // 使用统一的字段名
                });
                if (file.duplicate === "Y") {
                    fileObj.folder = DUPLICATE_FILE_FOLDER_ID;
                } else if (file.failed === "Y") {
                    fileObj.folder = FAILED_FILE_FOLDER_ID;
                } else {
                    fileObj.folder = PROCESSED_FILE_FOLDER_ID;
                }

                fileObj.save();
            });
        }
    } catch (err) {
        log.audit('File Moving Error', err.name + ' : ' + err.message);
    }
}

关键修改点

  • Reduce阶段:用JSON.stringify()将对象转为字符串后写入,确保数据序列化正确;统一字段名为fileId,避免拼写错误。
  • Summarize阶段:通过context.output.iterator()遍历所有Reduce输出结果,收集到局部变量fileList中;修正字段名引用,确保能正确获取文件ID。

内容的提问来源于stack exchange,提问作者Curious Explorer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 04:00:03