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

149
Visualizações
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 Respostas
Responde à pergunta

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 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