I have a collection in MongoDb that has documents "flights" which contain a field array of objects. I want to update one property of one object at a time. In order to do so, I have to use two filters: One in order to select the document that I want to update, and a second one to select the object in the array. I am using arrayFilters with Mongoose as follows: This is my Flight shema
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const flightSchema = new Schema({
flightName :{ type : String, required :true},
sits : {type : Array, required : true}, //[{n:1, d:f, s:f}]
origin : {type: String, required : true},
destination : {type : String, required: true},
departure : {type : Date, required : true},
arrival : {type : Date, required : true}
})
module.exports = mongoose.model('Flight', flightSchema)
// Models/Flight.js
{
flightName:a164651,
origin : Monterrey,
detination : Cancun,
sits: [{
sitNumber:1,
isAvailable : true,
isSuspended : false
},
{
sitNumber:2,
isAvailable : true,
isSuspended :false
}
]
}
Lets imagine that I want to update the property IsSuspended from false to true in the object with sitNumber : 2.
//Controllers dashboard.js
blockSit : async (req, res) =>{
try {
const flight = req.body.flightName
const sit = req.body.sitToBlock //sit es 2
const updateSit = await Flight.updateOne(
{"flightName" : flight},
{ "$set" : {"sits.$[si].isSuspended" : true} },
{"arrayFilters" :[ { "si.sitNumber" :sit} ]}
)
console.log(updateSit)
}
catch (error) {
console.log(error)
}
}
As far as I can see my sintaxis is correct. However I keep receiving the following error message:
Error: Could not find path "sits.0.sitNumber" in schema
I do not have to use arrayfilters necesarily. I am open to try any other solution that allows me to update a property in a nested array of objects with mongoose.
CodePudding user response:
It looks like your sits
field is array of sub-documents but there is not a schema to describe the fields. Try defining the schema.
const sitSchema = new Schema({
sitNumber: Number,
isAvailable: Boolean,
isSuspended: Boolean,
// etc
});
// in the flight schema
sits: [sitSchema],
CodePudding user response:
This is how I solved:
First I needed to use the method findOneandUpdate in Mongoose. Also, I added to arrayFilters the property new and set it to true.
blockSit : async (req, res) =>{
try {
const flight = req.body.flightName
console.log(flight)
const sit = req.body.sit
console.log(sit)
const updateSit = await Flight.findOneAndUpdate(
{"flightName" : flight},
{ "$set" : {"sits.$[si].isSuspended" : true, "sits.$[si].isAvailable": false} },
{"arrayFilters" :[ { "si.sitNumber" :sit} ], new : true}
)
res.send(updateSit)
}
catch (error) {
console.log(error)
}
},