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

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);

代码存在的关键问题:

  1. 错误将API URL当作MongoDB集合调用find(),API请求需要用HTTP库实现
  2. forEach是异步迭代,无法同步赋值id,且逻辑完全错误
  3. 缺少CSV导出的实现逻辑
  4. 未正确处理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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 17:36:23