Home > other >  Update value inside array of object in mongoose
Update value inside array of object in mongoose

Time:10-20

I have a notification schema in mongoose:

var mongoose = require('mongoose');
var schema = mongoose.Schema;

var notificationSchema = new schema({
    createdOn:{type: Date, default: Date.now},
    createdBy:{type: String, required:true},
    sentTo:{type: Array, required:true},
    content:{type:Object}
});



module.exports = mongoose.model('notification',notificationSchema);

data would be like this :

{
        "_id" : ObjectId("6350dee274edf5586dc86099"),
        "sentTo" : [
            {
                "username" : "user1",
                "status" : 0
            },
            {
                "username" : "user2",
                "status" : 0
            },
            {
                "username" : "user3",
                "status" : 0
            },
            {
                "username" : "user4",
                "status" : 0
            }
        ],
        "status" : 0,
        "createdOn" : ISODate("2022-10-20T05:38:42.656Z"),
        "createdBy" : "system",
        "content" : {
            "text" : "This is content"
        }

    }
{
        "_id" : ObjectId("6350dee274edf5586dc86099"),
        "sentTo" : [
            {
                "username" : "user1",
                "status" : 0
            },
            {
                "username" : "user3",
                "status" : 0
            }
        ],
        "status" : 0,
        "createdOn" : ISODate("2022-10-20T05:38:42.656Z"),
        "createdBy" : "system",
        "content" : {
            "text" : "This is another content"
        }

    }

Now i want to update status of all notification whose username = user3 to 1

status values

0 -> new

1 -> seen

2 -> read

Now new document should look like this

{
        "_id" : ObjectId("6350dee274edf5586dc86099"),
        "sentTo" : [
            {
                "username" : "user1",
                "status" : 0
            },
            {
                "username" : "user2",
                "status" : 0
            },
            {
                "username" : "user3",
                "status" : 1
            },
            {
                "username" : "user4",
                "status" : 0
            }
        ],
        "status" : 0,
        "createdOn" : ISODate("2022-10-20T05:38:42.656Z"),
        "createdBy" : "system",
        "content" : {
            "text" : "This is content"
        }

    }
{
        "_id" : ObjectId("6350dee274edf5586dc86099"),
        "sentTo" : [
            {
                "username" : "user1",
                "status" : 0
            },
            {
                "username" : "user3",
                "status" : 1
            }
        ],
        "status" : 0,
        "createdOn" : ISODate("2022-10-20T05:38:42.656Z"),
        "createdBy" : "system",
        "content" : {
            "text" : "This is another content"
        }

    }

what can be the query : As of now my query is :

let filters = {};
let updateObj = {};
filters['sentTo.username'] = "user3";
filters['sentTo.status'] = {$lt: 2} //only update whose status is less than 2
updateObj['sentTo.$.status'] = 1;

Notification.updateMany(filters, updateObj, function (err, doc) {
     if(err){
          console.log(err)
     }
})

but above query is updating the status of 1st element of the array.

CodePudding user response:

You can do it with $elemMatch and positional operator - $:

db.collection.update({
  "sentTo": {
    "$elemMatch": {
      "username": "user3",
      "status": {
        "$lt": 2
      }
    }
  }
},
{
  "$set": {
    "sentTo.$.status": 1
  }
},
{
  "multi": true
})

Working example

  • Related