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

151
Views
Actualización de la colección MongoDB: inicialice un documento con valores predeterminados

Estoy tratando de lidiar con series de tiempo usando MongoDB. La solución común adoptada por la comunidad es usar subdocumentos para almacenar información en diferentes niveles de granularidad (consulte Diseño de esquema para datos de series temporales en MongoDB ).

Por ejemplo, echa un vistazo al siguiente documento:

 { timestamp_minute: ISODate("2013-10-10T23:06:00.000Z"), type: “memory_used”, values: [ 999999, // 1 second … 1000000, // nth second 1500000, // n+1th second … 2000000 // 60th ] }

El documento está indexado por información de minutos y contiene un subdocumento que almacena información más detallada para cada segundo.

Hasta aquí todo bien. Este tipo de enfoque requiere una optimización para funcionar correctamente:

Otra optimización [..] es preasignar todos los documentos para el próximo período de tiempo; Esto nunca hace que un documento existente crezca o se mueva en el disco.

Para implementar la optimización anterior, se podría usar la propiedad $setOnInsert en el método de update .

 db.getCollection('aCollection').update( { timestamp_minute: ISODate("2013-10-10T23:06:00.000Z"), type: “memory_used” }, { $setOnInsert: { values: {'0': 0, '1': 0, '2': 0}}, $inc: {"values.30": 1} }, { upsert: true } )

El problema es que no es posible utilizar el mismo campo en la misma actualización en dos operaciones diferentes. La instrucción de actualización anterior genera el siguiente error:

 Cannot update 'values' and 'values.30' at the same time

Este problema se rastrea en este problema .

Mi pregunta es: ¿hay alguna solución? Prefijo que no puedo usar ningún lote que preasigne documentos vacíos, porque no puedo saber a priori el valor de los campos indexados (en el ejemplo anterior, los valores del campo type .

Gracias por adelantado.

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Mis colegas y yo encontramos una solución. Podemos llamarlo inicialización de tres pasos .

Recuerda que MongoDB garantiza la atomicidad de las operaciones sobre un único documento. Con este hecho en mente podemos operar de la siguiente manera:

  1. Intente actualizar el documento, incrementando correctamente los contadores en un período de tiempo específico. No haga ningún upsert, solo una operación de actualización a la antigua. Recuerde que la ejecución de una declaración de actualización devuelve la cantidad de documentos escritos. Si el número de documentos escritos es mayor que cero, ya está.
  2. Si el número de documentos escritos por la actualización es cero, significa que el documento relativo a actualizar aún no está presente en la colección. Intente insertar todo el documento para las etiquetas especificadas. Poner todos los contadores (valores de campo) a cero. Además, la ejecución de una declaración de inserción devuelve el número de documentos escritos. Si devuelve cero o lanza una excepción, no importa: significa que algún otro proceso ya había insertado el documento para las mismas etiquetas.
  3. Ejecute la misma actualización anterior nuevamente.

El código debería parecerse a algo similar al siguiente fragmento de código.

 // Firt of all, try the update var result = db.test.update( {timestamp_minute: ISODate("2013-10-10T23:06:00.000Z"), type: “memory_used”}, {$inc: {"values.39": 1}}, {upsert: false} ); // If the update do not succeed, then try to insert the document if (result.nModified === 0) { try { db.test.insert(/* Put here the whole document */); } catch (err) { console.log(err); } // Here we are sure that the document exists. // Retry to execute the update statement db.test.update(/* Same update as above */); }

El procedimiento anterior funciona si se cumple una condición previa: el valor _id debe derivarse de otros campos en el documento. En nuestro ejemplo, el valor de _id sería '2013-10-10T23:06:00.000Z-memory_used . Solo usando esta técnica, el inserto en el punto 2 fallará correctamente.

over 4 years ago · Santiago Trujillo 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!