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

Node.js读取CSV转JSON异步循环更新MongoDB的实现问题

用Node.js读取CSV并批量更新MongoDB数据的异步实现方案

我尝试用Node.js把CSV文件转成JSON数组后更新MongoDB,但循环处理时遇到Promise相关问题。现有代码能不能通过循环完成数据库更新?如果不行,该怎么用Node.js异步实现?


现有代码的核心问题

你的代码无法正常完成更新,主要是这几个问题:

  • map函数里直接用await,但map不会等待异步操作完成,导致所有更新请求同时发起,既无法保证执行顺序,还可能引发MongoDB连接池溢出
  • findOneAndUpdate缺少匹配条件和更新字段,根本没法完成有效更新
  • result变量定义在map内部,外部console.log(result)会直接报错

可行的异步实现方案

针对批量更新场景,有两种靠谱的异步处理方式,按需选择:

方案1:串行处理(适合小数据量)

用for...of循环逐个处理,每次等待当前更新完成后再执行下一个,逻辑简单易调试。

方案2:并行控制(适合大数据量)

用Promise.all()分批处理,控制每批并发数,避免给MongoDB造成过大压力。


修改后的完整代码

import csvtojson from "csvtojson";
import { MongoClient } from "mongodb";
const csvFilePath = "./data.csv";
const uri = "mongodb://localhost:27017";

// 列出数据库(保留原有逻辑)
async function listDatabases(client) {
  const databasesList = await client.db().admin().listDatabases();
  console.log("Databases:");
  databasesList.databases.forEach((db) => console.log(` - ${db.name}`));
}

async function main() {
  const client = new MongoClient(uri);
  try {
    await client.connect();
    await listDatabases(client);
  } catch (e) {
    console.error(e);
  } finally {
    await client.close();
  }
}
main().catch(console.error);

async function updateData() {
  const client = new MongoClient(uri);
  try {
    // 1. 读取CSV并转成JSON数组
    const csvData = await csvtojson().fromFile(csvFilePath);
    console.log(`读取到 ${csvData.length} 条待更新数据`);

    // 2. 连接MongoDB
    await client.connect();
    const db = client.db("nabatiform");
    const usersCollection = db.collection("users");

    // ========== 方案1:串行处理 ==========
    for (const item of csvData) {
      // 以NIK作为唯一匹配条件(确保更新正确的用户)
      const filter = { NIK: item.NIK };
      // 要更新的字段(注意CSV的Plant是大写,MongoDB里是小写plant,统一字段名)
      const updateDoc = {
        $set: {
          fullname: item.fullname,
          Group_Shift: item.Group_Shift,
          plant: item.Plant,
          Gedung_Zona: item.Gedung_Zona,
          Sector: item.Sector,
          SPV: item.SPV,
          updatedAt: Date.now() // 更新时间戳
        }
      };
      // 可选:如果没匹配到文档,是否插入新文档(按需设置为true/false)
      const options = { upsert: false };

      const result = await usersCollection.findOneAndUpdate(filter, updateDoc, options);
      console.log(`NIK ${item.NIK}:`, result.matchedCount ? "更新成功" : "未找到匹配文档");
    }

    // ========== 方案2:并行分批处理(注释掉方案1后启用) ==========
    // const batchSize = 10; // 每批处理10条,可根据服务器配置调整
    // for (let i = 0; i < csvData.length; i += batchSize) {
    //   const batch = csvData.slice(i, i + batchSize);
    //   await Promise.all(batch.map(async (item) => {
    //     const filter = { NIK: item.NIK };
    //     const updateDoc = {
    //       $set: {
    //         fullname: item.fullname,
    //         Group_Shift: item.Group_Shift,
    //         plant: item.Plant,
    //         Gedung_Zona: item.Gedung_Zona,
    //         Sector: item.Sector,
    //         SPV: item.SPV,
    //         updatedAt: Date.now()
    //       }
    //     };
    //     return usersCollection.findOneAndUpdate(filter, updateDoc, { upsert: false });
    //   }));
    //   console.log(`完成第 ${Math.floor(i/batchSize)+1} 批更新`);
    // }

  } catch (e) {
    console.error("更新失败:", e);
  } finally {
    await client.close();
    console.log("数据库连接已关闭");
  }
}

updateData().catch(console.error);

CSV转换后的JSON结果

[
  {
    "NIK": "22000028",
    "Plant": "Majalasgka",
    "fullname": "FERI FsaYAH",
    "Group_Shift": "R1",
    "Gedung_Zona": "Gas A",
    "Sector": "SEKTOas 08",
    "SPV": "TasI SUasWATI"
  },
  {
    "NIK": "22000330",
    "Plant": "Majaaka",
    "fullname": "AYasdMAYANTI",
    "Group_Shift": "NSHT",
    "Gedung_Zona": "GEDU",
    "Sector": "SE-08",
    "SPV": "TI"
  }
]

MongoDB文档示例

{
  "_id": { "$oid": "6369b17b11e02557349d8de5" },
  "fullname": "EGA PERMANA SAPUTRA",
  "password": "$2b$10$TuKKwzIxmqvnJfR8LRV/zu1s.Gqpt4yANLAcNNFQ6pqTuLL82.00q",
  "NIK": "17000691",
  "status": "active",
  "department": "Prodaucasdfation",
  "position": "Foreasdman",
  "Group_Shift": "R1",
  "role": "user",
  "__v": 0,
  "createdAt": 1667871099,
  "updatedAt": 1669025651,
  "userInformation": {},
  "plant": "Majasangka"
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 10:51:09