Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

138
Views
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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!