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

453
Vistas
MongoDB decrement until zero

I would like to achieve an operation in MongoDB that would be analogous to doc.value = max(doc.value - amount, 0). I could do it by fetching document, updating its value then saving it, but is it possible with an atomic operation to avoid problems with synchronisation of parallel decrements?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

It is, in fact, possible to achieve with a single operation. All you need is an aggregation pipeline inside an update operator.

Let's say you have a doc that looks like this:

{
    "key": 1,
    value: 30
}

You want to subtract x from value and if the resulting value is less than zero, set value to 0, otherwise set it to whatever value - x is. Here is an update aggregator you need. In this example I am subtracting 20 from value.

db.collection.update({
  key: 1
},
[
  {
    $set: {
      "value": {
        $cond: [
          {
            $gt: [
              {
                $subtract: [
                  "$value",
                  20
                ]
              },
              0
            ]
          },
          {
            $subtract: [
              "$value",
              20
            ]
          },
          0
        ]
      }
    }
  }
])

The result will be:

  {
    "key": 1,
    "value": 10
  }

But if you change 20 to, say 44, the result is:

  {
    "key": 1,
    "value": 0
  }

Here is a Playground for you: https://mongoplayground.net/p/Y9yO6v9Oca8

over 4 years ago · Santiago Trujillo Denunciar

0

Kudos to codemonkey's response for providing a solution using aggregation pipelines for an atomic transaction.

Here's a slightly simpler aggregation pipeline that takes advantage of the $max operator:

db.collection.update({},
[
  {
    $set: {
      "value": {
        $max: [
          0,
          {
            $subtract: [
              "$value",
              20
            ]
          }
        ]
      }
    }
  }
],
{
  multi: true
})

The pipeline sets the value to the maximum of 0 and the result of the decrement.

Playground

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