MongoDB, procesar un archivo JSON registro por registro

Archivada en Desarrollo Web

MongoDB, procesar un archivo JSON registro por registro

En el artículo anterior vimos como convertir un archivo CSV en JSON para usarlo con MongoDB, ahora vamos a continuar desde el punto en que nos quedamos para subir los datos a MongoDB pero con un proceso de registro por registro.

Es posible procesar un archivo completo e insertar su contenido en MongoDB, pero los archivos que vamos a usar tienen un pequeño problema que impide usarlo.

  • Primero, en la colección, no usamos el folio como identificador, sino el propio objeto _id de MongoDB
  • Segundo, los archivos contienen datos repetidos. Me explico, en marzo recibimos los trámites de enero, febrero y algunos de marzo, pero el mes que contaba era enero; en abril, de febrero, marzo y algo de abril; en mayo, recibimos de marzo, abril y unos de mayo, etc.

Esto hace que se repitan los folios, por lo que se se necesita hacer un movimiento que se llama en inglés upsert que consiste en buscar el folio y si lo encuentra hace una actualización (update); si no lo encuentra, se hace una inserción (insert).

Lo anterior se logra con una sentencia similara a la siguiente:

db.collection().update(búsqueda, registro, {upsert: true})

Tenemos que recorrer nuevamente todo el archivo, para insertar uno a uno cada registro, usando como filtro el FOLIO y el trámite a actualizar/insertar, es decir, a upsertar como parámetro. Es importante entender que esto funciona con las promesas de JavaScript, por lo que vamos a usar una callback para contar los registros procesados.

Aprovechamos para procesar nuevamente las fechas, para asegurar el correcto adecuado de las fechas.

Así que pasan dos cosas, primero se lee cada registro y se manda a MongoDb para hacer el upsert, pero como esto sucede muy rápido, se acumulan en un pool y se van procesando a la velocidad de MongoDB. Adicionalmente, después del upsert exitoso, se aumenta un contador, solo para hacer más amena la espera. Este es el script completo.

'use strict'

const jsonSalida = 'salida.json'
const mongoURI = 'mongodb://localhost:27017/cmi'

const moment = require('moment')
const _ = require('lodash')
const fs = require('fs')
const MongoClient = require('mongodb').MongoClient

const datos = fs.readFileSync(jsonSalida, 'utf8')
const tramites = JSON.parse(datos)
let totalTramites = tramites.length
console.log(`Se procesarán ${totalTramites} trámites`)

/**
 * @function fromFile El archivo que se procesa
 * @param {{folio: string}} Fecha disponible
 * @param {{fecha_tramite: string}} La fecha de trámite
 */
MongoClient.connect(mongoURI, (err, db) => {
  if (err) console.log(err)
  let conteo = 0

  _.forEach(tramites, (tramite, idx) => {
    _.forEach(tramite, (valor, campo) => {
      if (moment(tramite[campo], moment.ISO_8601).isValid()) {
        tramite[campo] = new Date(moment(tramite[campo]).format())
      }
    })
    db.collection('cecyrd')
      .update({FOLIO: tramite.FOLIO}, tramite, {upsert: true}, (err, res) => {
        if (err) console.log(err)
        conteo++
        if ((conteo % 5000) === 0) console.log(`Se han procesado ${conteo} tramites.`)
    })
  })

  db.close()
  console.log(`proceso terminado, se cargaron ${conteo} trámites.`)
})

Photo by Tobias van Schneider on Unsplash.

Javier Sanchez Toledano

Auditor Líder ISO 9000 ● Desarrollo Web Full Stack ● Django/Python ● JavaScript · NodeJS · Angular · VueJS · EmberJS ● Swift 4 ● WordPress · Genesis Framework ● Lector ● Fotografo aficionado ● Generación X ● Soy de Tlaxcala

Tlaxcala, México

Comentarios