Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

134
Vistas
Agregue un nuevo campo a todos los documentos de una colección con el valor del campo del documento en MongoDB (Mongoose) con registros de más de 300K

Tengo dificultades para agregar otro campo a todos los registros de la colección del user con un valor de cada documento. Estoy familiarizado con el uso $set con db.model.updateMany y $addFields con canalización de agregación. He usado ambos para resolver problemas en el pasado, en este caso, tengo que realizar algunos cálculos lógicos antes de agregar el valor. , justo aquí es donde radica mi problema.

Digamos, tengo el esquema como este:

 { "users": [ { "wallets": {...}, "avatar": "", "isVerified": false, "suspended": false, "country": "Nigeria", "_id": "123", "resetPasswordToken": "", "email": "example@gmail.com", "phone": "08012398743", "name": "Agbakwuru Nnaemeka Kennedy ", "role": "user", }, {...} }

Quiero agregar un nuevo campo phoneNumber , que tomará el valor del phone de campo existente, pero antes de agregarlo, me gustaría ejecutar una lógica en él, ya que algunos de los valores del teléfono tienen espacios en blanco, la mayoría de ellos no son correctos formateado, y me gustaría anteponer el código de país al valor del phone , antes de agregarlo al nuevo campo phoneNumber .

Pude hacer esto usando un cursor del método Mongoose db.mode.aggregate , con $match filter, y agregando el campo a cada documento con la canalización agregada $addFields , esto demostró tomar mucho tiempo, tuve para detener la operación, ya que está tardando demasiado en ejecutarse.

Me gustaría creer que hay una mejor manera, por favor, agradeceré cualquier ayuda.

Editar:

Aquí está la agregación que estoy usando:

 const userCursor = User.aggregate([{$match: {phone: {$exists: true}}}]); for await (const doc of userCursor) { await User.findByIdAndUpdate(doc._id, {$set: { phoneNumber: convertPhoneNumber({phoneNumber: doc.phone.replace(/\s+/g, "")})} }); }

El convertPhoneNumber es un método de ayuda que definí en mis utils para anteponer el código de trato del país al número de teléfono.

about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

Intentaría ejecutar un script como ese directamente en la línea de comando de mongo , o Robo3T:

 db.getCollection("users").find({}).forEach( doc => { doc.users.forEach( user => { // do your logic here let phoneNumber = "12345"; phoneNumber = "+007" + phoneNumber; user.phoneNumber = phoneNumber; }) db.users.save(doc); })

Todavía tomará un tiempo en más de 300k documentos, pero espere unos minutos.

about 4 years ago · Juan Pablo Isaza Denunciar

0

Puede usar $function y llamar a ese código javascript en la base de datos.

Esto requiere >=MongoDB 4.4

 db.Users.update( {phone: {$exists: true}}, [{$set: {phoneNumber: { "$function": { "body": YOUR_convertPhoneNumber_FUNCTION_DEF, "args": ["$phoneNumber"], "lang": "js" } }])

Además, si el código de convertPhoneNumber se puede escribir en MongodBD usando operadores agregados, también puede evitar el javascript.

Lo anterior es una actualización de tubería y podemos usar todos los operadores agregados al actualizar.


Editar

Si mongoose tiene problemas con la $function o el método del controlador nodejs tiene problemas con la actualización de la canalización, también puede hacerlo.

 db.runCommand( { update: "yourCollectionName", updates: [ { q: {phone: {$exists: true}}, u: [{$set: {phoneNumber: { "$function": { "body": YOUR_convertPhoneNumber_FUNCTION_DEF, "args": ["$phoneNumber"], "lang": "js" } }], multi: true } ], ordered: false } )
about 4 years ago · Juan Pablo Isaza Denunciar

0

Puede probar la operación masiva , esto actualiza la colección en lotes de 1000 documentos:

 var bulkOperations = []; db.getCollection("users").find({}).forEach(doc => { doc.users.forEach(user => { user.phoneNumber = convertPhoneNumber({phoneNumber: user.phone.replace(/\s+/g, "")}); }) bulkOperations.push({ updateOne: { filter: { id: doc._id }, update: { $set: { users: doc.users } } } }); if (bulkOperations.length > 1000) { db.getCollection("users").bulkWrite(bulkOperations, { ordered: false }); bulkOperations = []; } }) if (bulkOperations.length > 0) db.getCollection("users").bulkWrite(bulkOperations, { ordered: false });
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda