Search code examples
javascriptmongodbmongoosemongoose-schema

How to find and update an element in an array in mongoose?


I have a following schema. Each store has an id and a list of buckets.

const storeSchema = new mongoose.Schema({
    _id: String
    bucket: [
        {
            sold: Boolean,
            location: {
                state: String,  
                location: String,
                description: String,
            },
            fruits: [          
                {
                    item: String,      // apple, pear, orange
                    status: String,  // fresh, ripe, rotten
                    completed: Date
                }
            ]
        }
    ]
}, {collection: 'store'});

Now I have a store that has two buckets, shown in below. I want to make edit to the first bucket (that has index position of 0 in MongoDB). How can I do this? In addition, how can I change the first bucket apple's status from "fresh" to "ripe" without making any change to other fruits in the same bucket or any fruits in another bucket?

{
    _id: "1"
    bucket: [
        {
            sold: false,
            location: {
                state: "CA",  
                location: "LA",
                description: "something",
            },
            fruits: [          
                {
                    item: "apple",      // apple, pear, orange
                    status: "fresh",  // fresh, ripe, rotten
                    completed: null
                },
                {
                    item: "pear",      // apple, pear, orange
                    status: "fresh",  // fresh, ripe, rotten
                    completed: null
                },
            ]
        },
        {
            sold: false,
            location: {
                state: "CA",  
                location: "LA",
                description: "something",
            },
            fruits: [          
                {
                    item: "apple",      // apple, pear, orange
                    status: "fresh",  // fresh, ripe, rotten
                    completed: null
                },
                {
                    item: "orange",      // apple, pear, orange
                    status: "fresh",  // fresh, ripe, rotten
                    completed: null
                },
            ]
        },
    ]
}

In short: How can I change the first bucket (index 0) in this store from sold: false to sold: true and its fruits item: 'apple''s status from 'fresh' to 'ripe' using mongoose.


Solution

  • Do a findOne query on the Store model and manually update the store at index 0.

    Then call store.save() method

    Store.findOne({ _id: 1 }).then(store => {
    
      if (!store) {
        return 'Store not found';
      }
    
      store.bucket[0].solid  = true;
      store.bucket[0].fruit  = store.bucket[0].fruit.map(x => {
        if (x.item === 'apple') {
          x.status = 'ripe';
        }
        return x
      });
    
      store.save();
    });
    

    To add an orange item to fruits if it doesn't exist

    const orange = store.bucket[0].fruit.find(x => x.item === 'orange');
    
    if (!orange) {
      store.bucket[0].fruit.push({
        item: 'orange',
        status: 'fresh',
        completed: null
      })
    }