Mongoose save() does not update database

Viewed 398

I am working on a package of files for download, using MongoDB version 4.4.8 and mongoose version 5.13.5, and I am running into an issue. Whenever a file is removed from the package, it does not update. Here is code I am trying to run:

app.post('/remove-package-file', (req, res, next) => {
      let { package, file } = req.body
      if (!package || !file) return res.status(500).json({ error: true, message: 'Please specify file and package to remove' })
      Package.findOne({ _id: package }).then(pack => {
        if (!pack) return res.status(500).json({ error: true, message: 'Unable to locate package' })
        if (!pack.files.includes(file)) return res.status(500).json({ error: true, message: 'File is not in package' })
        File.findOne({ _id: file }).then(file => {
          if (!file) return res.status(500).json({ error: true, message: 'Unable to locate file' })
          pack.files.pull(file._id)
          pack.size = pack.size-file.stats.size
          pack.markModified('size')
          pack.markModified('files')
          pack.save().then(result => {
            console.log(result)
            Package.findOne({_id: result._id}).then(result2 => {
              console.log(result2)
              res.status(200).json({ error: false, package: result2 })
            }).catch(e => {
              saveError(e)
              return res.status(500).json({ error: true, message: 'DB error' })
            })
          }).catch(e => {
            saveError(e)
            return res.status(500).json({ error: true, message: 'DB error' })
          })
        }).catch(e => {
          saveError(e)
          return res.status(500).json({ error: true, message: 'DB error' })
        })
      }).catch(e => {
        saveError(e)
        return res.status(500).json({ error: true, message: 'DB error' })
      })
    })

Outputs:

{
  titles: [ '6127d98a5b5df7462cb166d5' ],
  files: [ '6127da305b5df7462cb166db' ],
  accessLog: [],
  successfulDownloads: [],
  timesDownloaded: 0,
  recipients: [ '6126da9ac081145ab46039e6' ],
  _id: 6128363fc03f9d23f86258ac,
  size: -281171,
  expires: 2021-08-28T00:47:59.654Z,
  name: 't2',
  createdBy: '6126da9ac081145ab46039e6',
  link: 'http://localhost:4232/download-package?_id=6128363fc03f9d23f86258ac',
  date: 2021-08-27T00:47:59.658Z,
  __v: 7
}
{
  titles: [ '6127d98a5b5df7462cb166d5' ],
  files: [ '6127da9c5b5df7462cb166f9', '6127da305b5df7462cb166db' ],
  accessLog: [],
  successfulDownloads: [],
  timesDownloaded: 0,
  recipients: [ '6126da9ac081145ab46039e6' ],
  _id: 6128363fc03f9d23f86258ac,
  size: -281171,
  expires: 2021-08-28T00:47:59.654Z,
  name: 't2',
  createdBy: '6126da9ac081145ab46039e6',
  link: 'http://localhost:4232/download-package?_id=6128363fc03f9d23f86258ac',
  date: 2021-08-27T00:47:59.658Z,
  __v: 7
}

It is showing that the file is updated correctly, but when queried afterward it still has the same values in the files array but the size is changed and it has a new version number. Please let me know if you have any idea why this is happening.

3 Answers

Which MongoDB version you using?

Mongo v5.0 and grether version deprecated .save() function and alternatives are .insert() / .insertMany()

As per your code you doing update operations then you can use .updateOne() or .updateMany()

https://docs.mongodb.com/v5.0/release-notes/5.0-compatibility/ here you will find deprecated functions

I haven't seen any pull method before, as in pack.files.pull(file._id).

If that function doesn't actually exist/work, a filter like this could be used:

pack.files = pack.files.filter((str) => str !== file._id)

The solution I found was that I needed to define the type of the field as [String] instead of Array in my mongoose model like so:

const mongo = require('mongoose');
const Schema = mongo.Schema({
    _id: mongo.Schema.Types.ObjectId,
    files: [String],
    link: String
})
module.exports = mongo.model('Directory', Schema, 'Directory');

This makes it so the objectIds are always treated as strings in the array and not as objectIds which will not match to a string when using the $update.pull method from mongoose.

This was confusing because I was saving the _ids as strings using new mongoose.Types.ObjectId().toHexString() when saving but these were converted back to objects I suppose.

Related