Java开发者求助Node.js脚本:MongoDB查询、API调用及CSV导出
问题:MongoDB数据提取、API调用与CSV导出的Node.js实现
需求概述
- 从MongoDB的
merchant_wallet集合获取_id、document、corporateName字段 - 用每个
_id作为参数调用指定API,获取client_id和client_secret - 将上述所有字段合并导出为单个CSV文件
现有代码核心问题
const {MongoClient} = require('mongodb'); const uri = "mongodb+srv://<privateInfo>/"; const client = new MongoClient(uri); async function run() { try { const database = client.db("merchant-profile"); const ecs = database.collection("merchant_wallet"); const api = `https://<prodAPI>/v1/merchant/wallet/${id}/oauth2`; const ecOpt = {_id: 1, document: 1, corporateName: 1}; const credOpt = {client_id: 1, client_secret: 1}; const ec = ecs.find({}).project(ecOpt); let id = ec.forEach(id => cred._id); const cred = api.find({}).project(credOpt); await cred.forEach(console.dir); } finally { await client.close(); } } run().catch(console.dir);
代码存在的关键问题:
- 错误将API URL当作MongoDB集合调用
find(),API请求需要用HTTP库实现forEach是异步迭代,无法同步赋值id,且逻辑完全错误- 缺少CSV导出的实现逻辑
- 未正确处理MongoDB游标异步特性(
find()返回游标而非直接数据)
实现思路
1. 完善MongoDB数据读取
- 使用
toArray()将MongoDB游标转为数组,方便后续同步遍历 - 确保只查询所需的
_id、document、corporateName字段
2. 实现API调用逻辑
- 安装HTTP请求库(如
node-fetch),发起请求到目标API - 遍历MongoDB返回的文档数组,用每个文档的
_id替换API URL中的占位符 - 处理API请求的异步逻辑,可选择串行遍历(避免并发过高)或
Promise.all控制并发 - 捕获API请求错误,避免流程中断
3. CSV导出实现
- 使用第三方库
csv-writer简化CSV生成(或手动拼接CSV格式) - 收集所有合并后的字段数据(
document、corporateName、client_id、client_secret) - 写入CSV文件时处理特殊字符(如逗号、换行符)
修正方案(分步拆解)
步骤1:安装依赖
npm install mongodb node-fetch csv-writer
步骤2:修正MongoDB数据读取
将游标转为数组,获取完整的文档列表:
// 替换原有的ec = ecs.find({}).project(ecOpt)后的逻辑 const ecList = await ecs.find({}).project(ecOpt).toArray(); // ecList是包含所有目标字段的文档数组
步骤3:实现API调用与数据合并
遍历文档列表,发起API请求并合并所需字段:
const fetch = require('node-fetch'); const apiBaseUrl = "https://<prodAPI>/v1/merchant/wallet/{id}/oauth2"; const mergedData = []; for (const ec of ecList) { const apiUrl = apiBaseUrl.replace("{id}", ec._id); try { const response = await fetch(apiUrl); if (!response.ok) throw new Error(`HTTP错误: ${response.status}`); const cred = await response.json(); mergedData.push({ document: ec.document, corporateName: ec.corporateName, client_id: cred.client_id, client_secret: cred.client_secret }); } catch (err) { console.error(`ID ${ec._id}处理失败:`, err.message); // 错误数据保留基础字段,标记错误状态 mergedData.push({ document: ec.document, corporateName: ec.corporateName, client_id: "ERROR", client_secret: "ERROR" }); } }
步骤4:CSV导出实现
使用csv-writer生成CSV文件:
const createCsvWriter = require('csv-writer').createObjectCsvWriter; const csvWriter = createCsvWriter({ path: './merchant_credentials.csv', header: [ {id: 'document', title: 'DOCUMENT'}, {id: 'corporateName', title: 'CORPORATE_NAME'}, {id: 'client_id', title: 'CLIENT_ID'}, {id: 'client_secret', title: 'CLIENT_SECRET'} ] }); await csvWriter.writeRecords(mergedData); console.log('CSV文件导出完成');
完整修正代码
const { MongoClient } = require('mongodb'); const fetch = require('node-fetch'); const createCsvWriter = require('csv-writer').createObjectCsvWriter; const uri = "mongodb+srv://<privateInfo>/"; const client = new MongoClient(uri); const apiBaseUrl = "https://<prodAPI>/v1/merchant/wallet/{id}/oauth2"; async function run() { try { await client.connect(); const database = client.db("merchant-profile"); const ecs = database.collection("merchant_wallet"); const ecOpt = { _id: 1, document: 1, corporateName: 1 }; // 1. 从MongoDB获取数据 const ecList = await ecs.find({}).project(ecOpt).toArray(); console.log(`获取到${ecList.length}条商户数据`); // 2. 遍历调用API并合并数据 const mergedData = []; for (const ec of ecList) { const apiUrl = apiBaseUrl.replace("{id}", ec._id); try { const response = await fetch(apiUrl); if (!response.ok) throw new Error(`API响应错误: ${response.status}`); const cred = await response.json(); mergedData.push({ document: ec.document, corporateName: ec.corporateName, client_id: cred.client_id, client_secret: cred.client_secret }); } catch (error) { console.error(`处理ID ${ec._id}时出错:`, error.message); mergedData.push({ document: ec.document, corporateName: ec.corporateName, client_id: "ERROR", client_secret: "ERROR" }); } } // 3. 导出CSV const csvWriter = createCsvWriter({ path: './merchant_credentials.csv', header: [ { id: 'document', title: 'DOCUMENT' }, { id: 'corporateName', title: 'CORPORATE_NAME' }, { id: 'client_id', title: 'CLIENT_ID' }, { id: 'client_secret', title: 'CLIENT_SECRET' } ] }); await csvWriter.writeRecords(mergedData); console.log("CSV文件已成功生成"); } catch (err) { console.error("整体流程出错:", err); } finally { await client.close(); } } run();
内容的提问来源于stack exchange,提问作者Binyamin Ely
相关产品推荐
相关产品推荐

