'MongoDB Remove object key based on value

In my application, I have a MongoDB document that will be updated with $inc operation to increase/decrease the number in appliesTo object. Here is a sample object

{
  name: "test-document",
  appliesTo: {
    profiles: {
      Profile1: 3,
      Profile2: 1
    },
    tags: {
      Tag1: 7,
      Tag2: 1
    }
  }
}

After I'm running the following command

await db.items.updateOne({name: "test-document"}, {$inc: {'appliesTo.profiles.Profile2': -1})

my document will be changed to

{
  name: "test-document",
  appliesTo: {
    profiles: {
      Profile1: 3,
      Profile2: 0
    },
    tags: {
      Tag1: 7,
      Tag2: 1
    }
  }
}

I'm struggling with writing a query that will remove all keys, which values are 0. The only solution I have currently is to iterate over each key and update it using $unset command. But this is not an atomic operation

Is there a smarter way to handle it in one query?



Solution 1:[1]

There is no way to do both operations in a single regular update quey, you can try update with aggregation pipeline starting from MongoDB 4.2,

  • $cond to check is a key field's value greater than 1 then do $add operation otherwise remove it by $$REMOVE operator
await db.items.updateOne(
  { name: "test-document" },
  [{
    $set: {
      "appliesTo.profiles.Profile2": {
        $cond: [
          { $gt: ["$appliesTo.profiles.Profile2", 1] },
          { $add: ["$appliesTo.profiles.Profile2", -1] }
          "$$REMOVE"
        ]
      }
    }
  }]
)

Playground

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 turivishal