Adam Coster
Adam Coster

Reputation: 1462

Mongoose model.update and model.findOneAndUpdate are not actually updating

model.update and model.findOneAndUpdate do not actually perform updates even when they match documents.

I must be losing my mind, because a problem this large would surely be seen by others. (This is a dramatically simplified duplicate of a prior post I submitted after doing some more testing.)

I've been able to replicate this issue with multiple versions of Mongoose (4.0.7 and 5.3.2) and Node (v8 and v10), and in two completely different environments (Ubuntu 16.04 and Windows 10) with a tiny Node.js file:

const mongoose = require('mongoose');
mongoose.set('debug',true);
mongoose.connect('mongodb://localhost/db',{useNewUrlParser: true});
console.log(mongoose.version);
const model = mongoose.model(
  'tests',
  new mongoose.Schema({hello:String})
);
const test = new model({hello:'world'});
test.save(()=>{
  model.count({},(err,count)=>{
    console.log(count);
    model.findOneAndUpdate({},{dummy:true},{new:true},(updateErr,doc)=>{
      console.log(doc);
    });
  });
});

The result of running this is:

5.3.2
Mongoose: tests.insert({ hello: 'world', _id: ObjectId("5bbea605cb4a882433725bfe"), __v: 0 })
Mongoose: tests.count({}) {}
6
Mongoose: tests.findOne({ dummy: { '$ne': true } }) { new: true, fields: undefined }
{ _id: 5bbe9f7c5362642220dde2d7, hello: 'world', __v: 0 }

Whether I use update or findOneAndUpdate no updates actually occur, and that's true even if my search doc is the empty {}. The higher count is due to running this multiple times. I can run the update command directly in the mongo shell without trouble, and can confirm via the shell that nothing is getting updated.

Can anyone replicate this? Perhaps with fresh installs of Mongoose? Am I just being super duper dumb about something?

Upvotes: 0

Views: 765

Answers (1)

Adam Coster
Adam Coster

Reputation: 1462

Thanks to the fine folks over at the Mongoose GitHub, I've got the answer.

In short: updates are not run by Mongoose when they would only impact fields that are not defined in the schema.

In longer: when in strict mode (the default) if you use an update query that only impacts fields not in the schema, the query is converted into a find or similar query, or doesn't do anything at all. This is true even for an $unset operation on a field not specified in the schema. I ran into this when trying to remove a field from documents after taking that field out of my schema, and then in my minimal example was being dumb and didn't include the dummy field in the schema.

Upvotes: 1

Related Questions