JS24
JS24

Reputation: 458

Looping array from csv and update it to mongodb nodejs

So i try to read a CSV file to JSON array using node js, and i try to update it to mongodb, is it possible way to looping the data and update it to database base on the JSON using this code, if its not possible is there a way to do it asynchronously using node, because i keep getting promise issue? here is my code:

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

console.log(" ");
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);
  const data = await csvtojson().fromFile(csvFilePath);
  console.log(data.length);
  data.map((datas) => {
    // console.log(datas);
    console.log(Object.keys(datas), Object.values(datas));
  });
  try {
    await client.connect();
    const db = client.db("nabatiform");
    const stuff = db.collection("users");
    data.map((datas) => {
      // console.log(datas);
      console.log(Object.keys(datas), Object.values(datas));
const result = await stuff.findOneAndUpdate({})
    });
    
    
    console.log(result);
  } catch (e) {
    console.error(e);
  } finally {
    await client.close();
  }
}

updateData().catch(console.error);

here is my JSON that i read from CSV:

[{
    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'
  },
]

here is what its look like on my document on 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"
}

Upvotes: 0

Views: 148

Answers (3)

Lahiru Tennakoon
Lahiru Tennakoon

Reputation: 649

Use a forEach() loop to push each findOneAndUpdate() function to an array. Then execute all the promises asynchronously using Promise.all(). This is much faster than using await inside a map() or for loop.

async function updateData() {
  const promises = [];
  const client = new MongoClient(uri);
  const data = await csvtojson().fromFile(csvFilePath);
  console.log(data.length);
  data.map((datas) => {
    // console.log(datas);
    console.log(Object.keys(datas), Object.values(datas));
  });
  
  try {
    await client.connect();
    const db = client.db("nabatiform");
    const stuff = db.collection("users");
    
    data.forEach((datas) => {
      console.log(Object.keys(datas), Object.values(datas));
      
      // Push each promise to array
      promises.push(stuff.findOneAndUpdate({}));     
    });
    
    // Execute all promises
    await Promise.all(promises);       
    
    console.log(result);
  } catch (e) {
    console.error(e);
  } finally {
    await client.close();
  }
}

Upvotes: 1

rickhg12hs
rickhg12hs

Reputation: 11932

I'm no javascript wizard, but hopefully this is helpful.

Perhaps a little modification of your updateData function will make the updates. I don't really have a way to test it.

async function updateData() {
  const client = new MongoClient(uri);
  const data = await csvtojson().fromFile(csvFilePath);
  console.log(data.length);
  data.map((datas) => {
    // console.log(datas);
    console.log(Object.keys(datas), Object.values(datas));
  });
  try {
    await client.connect();
    const db = client.db("nabatiform");
    const stuff = db.collection("users");

    // Below here is what I modified.
    data.forEach(element => {
      const filter = Object.fromEntries(Object.entries(element).filter(elem =>
        elem[0] == "NIK"
      ));
      const updateFields = Object.fromEntries(Object.entries(element).filter(elem =>
        elem[0] != "NIK"
      ));
      const update = {$set: updateFields};
      const result = await stuff.findOneAndUpdate(filter, update);
    });   
    
    console.log(result);
  } catch (e) {
    console.error(e);
  } finally {
    await client.close();
  }
}

Upvotes: 1

Dhaval Italiya
Dhaval Italiya

Reputation: 449

use await while calling updateData()

await updateData().catch(console.error);

I whould suggest for loop instead of map because if you want yo use async and wait in the map it just won't work while for loop does not have that problem.

Upvotes: 1

Related Questions