Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

394
Visualizações
Cómo exportar de manera eficiente 3 millones de documentos de la colección MongoDB Atlas a un archivo CSV usando NodeJS

tenemos una colección en MongoDB Atlas con 3 millones de documentos y usando NodeJS necesitamos exportarlos a CSV. No podemos usar MONGOEXPORT o MONGODUMP, es un proceso que debe desarrollarse como una API.

Para ello estamos trabajando con la librería fast-csv, pero tenemos el problema de que debemos pasar un array al método fastcsv.write() como dato de entrada para la creación del CSV.

El problema es que la transformación a una matriz de los 3 millones de documentos devueltos por la consulta a Mongo consume mucho tiempo y memoria.

¿Podrías darnos una mano para saber cómo desarrollar esto para que funcione de la manera más eficiente posible?

Aquí hay una muestra del código que estamos probando.

ingrese la descripción de la imagen aquí

PD Preguntas que también nos pueden ayudar:

  1. ¿Conoce alguna biblioteca o forma de hacer esto de manera más eficiente?
  2. ¿Hay alguna manera de NO tener que convertir los datos devueltos en la consulta a una matriz para que se escriban en el archivo CSV?

Gracias.

 const aggCursor = colInventarioInstalaciones.aggregate(pipeline, pipelineOptions) .toArray((err, data) => { //<<===== taking a lot of time //console.log("se ejecuta punto 3 del metodo"); if (err) throw err; const ws = fs.createWriteStream("pruebaTC1.csv"); fastcsv.write(data, { headers: true }) //<<===== need to be array for write data in the file .on("finish", function() { var datetime = new Date(); console.log(datetime); console.log("Write to pruebaTC1.csv successfully!"); }).pipe(ws); });```
over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Personalmente, NUNCA recomendaría usar .toArray() para consultar un número indefinido/muy grande. de documentos, ya que le pide a nodejs que obtenga 3 millones de documentos de su base de datos y almacene todo en una matriz de humongosaurus en la memoria. Espero que tengas una computadora de alta especificación. Además, no escribirá nada en un archivo a menos que todo esté en la memoria, si eso sucede alguna vez.

En su lugar, estaría iterando el cursor para que, en un momento dado, solo tenga 1 documento en la memoria y lo canalice al flujo de escritura.

Dado que está leyendo 3 millones de documentos, llevará tiempo, solo es cuestión de cuánto. Al menos con este enfoque, escribirá los documentos en el archivo csv a medida que se leen, en lugar de escribir todo de una vez desde la memoria.

Escribí un pequeño script para iterar sobre todo a través cursor.next() , documento por documento, y lo probé.

 const { MongoClient } = require('mongodb'); const csv = require('fast-csv'); const fs = require('fs'); // or as an es module: // import { MongoClient } from 'mongodb' // Connection URL const url = 'supersecretmongourlhere'; const client = new MongoClient(url); // Database Name const dbName = 'db_name_here'; const run = async() => { try{ await client.connect(); console.log("db connected"); const db = client.db(dbName); console.time("X") const pipelineStages = [{ $match: { // your pipeline here } },{ $sort: { _id: -1 } },{ $limit: 50000 }] const cursor = db.collection('collection_name_here').aggregate(pipelineStages) const csvStream = csv.format({ headers: true }); const writeStream = fs.createWriteStream('./myfile.csv'); csvStream.pipe(writeStream).on('end',() => { console.log("DONE"); }).on('error',err => console.error(err)); while(await cursor.hasNext()){ const doc = await cursor.next(); csvStream.write(doc); console.log(`${doc._id} written`); } console.log('done') console.timeEnd("X") csvStream.end(); writeStream.end(); } catch(e) { console.error(e); } } run();

producción

Para 50000 documentos, 1:17,987s = 77987ms, 50000/77987 = 1,56ms/documento. 1.56*3000000 = 4680s = ~78mins

¿Es eso aceptable en su caso de uso?

Sí, sé que esta no es una solución muy rápida, pero funcionará.

Puede haber alguna forma de acelerarlo aún más obteniendo documentos en lotes de la base de datos, lo investigaré si puedo.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda