Home > Back-end >  Use arrayFilters in order to update a property of an object in nested array of objects, with Mongoos
Use arrayFilters in order to update a property of an object in nested array of objects, with Mongoos

Time:06-10

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

  • Related