Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use $cond in updateOne using mongoose?

I want to update a value in the mongodb depending on its previous value, if null (saved as string) then I will update it to a new value, otherwise I want to keep it as it is.
Here is my code:

User.updateOne({_id: user._id}, {$set: {
                        deviceId: {$cond: [{$eq: ['null']}, req.body.deviceId, 'null']}
                    }}, null, function (err, res){
                    if (err){
                        return done(err)
                    }else{
                        return done(null, user)
                    }
                })

But I get the following error (I believe it indicates that my syntax is not correct):

CastError: Cast to string failed for value "{ '$cond': [ { '$eq': [Array] }, 'MYDEVICEID', 'null' ] }" (type Object) at path "deviceId"
    at model.Query.exec (D:\X_APP\XAPP_BACKEND\node_modules\mongoose\lib\query.js:4478:21)
    at _update (D:\X_APP\XAPP_BACKEND\node_modules\mongoose\lib\query.js:4330:11)
    at model.Query.Query.updateOne (D:\X_APP\XAPP_BACKEND\node_modules\mongoose\lib\query.js:4229:10)
    at _update (D:\X_APP\XAPP_BACKEND\node_modules\mongoose\lib\model.js:3834:16)
    at Function.updateOne (D:\X_APP\XAPP_BACKEND\node_modules\mongoose\lib\model.js:3770:10)
    at file:///D:/X_APP/XAPP_BACKEND/middlewares/userMiddleware.js:24:32
    at processTicksAndRejections (internal/process/task_queues.js:95:5)

I searched and saw many applications using the Aggregation but is it possible to achieve it using my approach updateOne in mongoose? if yes, what is the issue with my application?

like image 771
Jagar Avatar asked Feb 02 '26 03:02

Jagar


2 Answers

The $cond is an aggregation operator you can not use in a simple update query,

if null (saved as string) then I will update it to a new value, otherwise I want to keep it as it is.

If you are trying to update a single field, i would suggest a simple approach,

You can check the condition in the query part if deviceId is null then update new deviceId otherwise it will ignore update operation,

await User.updateOne(
  { 
    _id: user._id,
    deviceId: "null"
  }, 
  {
    $set: {
      deviceId: req.body.deviceId
    }
  }, 
  null, 
  function (err, res){
    if (err){
      return done(err)
    }else{
      return done(null, user)
    }
  }
);

Second, as per your try, you can achieve by update with aggregation pipeline starting from MongoDB 4.2,

await User.updateOne(
  { _id: user._id }, 
  [{
    $set: {
      deviceId: {
        $cond: [
          { $eq: ["$deviceId", "null"] },
          req.body.deviceId,
          "null" // or you can use "$deviceId"
        ]
      }
    }
  }], 
  null, 
  function (err, res){
    if (err){
      return done(err)
    }else{
      return done(null, user)
    }
  }
)
like image 168
turivishal Avatar answered Feb 03 '26 18:02

turivishal


No, you can't use $cond with the update, MongoDB doesn't allow this.

But you still can achieve this by using this way: MongoDB update with condition

like image 43
Suneel K Khatri Avatar answered Feb 03 '26 17:02

Suneel K Khatri