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