Mongoose: $unset not working

Created on 17 Feb 2017  路  8Comments  路  Source: Automattic/mongoose

Do you want to request a feature or report a bug?
BUG

What is the current behavior?
When I try to unset a specific field it doesn't remove it from the collection. I ran mongoose in debug mode and saw following query, it doesn't have $unset field.
sessions.update({ isDeleted: false, 'deviceDetails.deviceType': { '$in': [ 'IOS' ] }, companyIdentifier: 'string', userRefNum: 'string' }, { '$set': { updatedAt: new Date("Fri, 17 Feb 2017 09:16:44 GMT") }, '$setOnInsert': { createdAt: new Date("Fri, 17 Feb 2017 09:16:44 GMT") } }, { multi: true, overwrite: undefined })

If the current behavior is a bug, please provide the steps to reproduce.
let query = { userRefNum: data.userRefNum, companyIdentifier: data.companyIdentifier, 'deviceDetails.deviceType': { $in: data.flushOldToken }, isDeleted: false }; DaoManager.update(MODEL, query, { $unset: { sessionToken: "" }, $set: { deletedAt: Date.now(), isDeleted: true } }, { multi: true, lean: true }, callback);

What is the expected behavior?
$unset in update query should remove the specified field.

Please mention your node.js, mongoose and MongoDB version.
mongodb v3.4.1, nodejs v6.6.0, mongoose v4.8.3

PS: It is working on mongoose v4.8.2

can't reproduce

Most helpful comment

I just stumbled on a similar issue, leaving this in case it helps someone else. Mongoose will strip from $unset and $set any properties that is not defined in your schema. You can't explicitly $unset or $set a property that is not defined in your schema. In my case I was getting:

Error: { MongoError: exception: '$unset' is empty. You must specify a field like so: {$unset: {<field>: ...}}

Even though i did pass an object to $unset, Mongoose was stripping the property since it wasn't set in the schema.

All 8 comments

@Harekam this seems to work for me:

const mongoose = require('mongoose');
const co = require('co');

mongoose.set('debug', true);
mongoose.Promise = global.Promise;

const GITHUB_ISSUE = `gh-4992`;

exec()
  .then(() => {
    console.log(`Successfuly ran program`);
    process.exit(0);
  })
  .catch(error => {
    console.error(`Error: ${ error }\n${ error.stack }`);
    process.exit(2);
  });

function exec() {
  return co(function*() {
    const db = mongoose.createConnection(`mongodb://localhost:27017/${ GITHUB_ISSUE }`);
    const schema = new mongoose.Schema({
      name: String
    });

    const Model = db.model('Model', schema);

    yield Model.remove({});

    const doc = yield Model.create({ name: 'Test' });

    yield Model.update({ _id: doc._id }, { $unset: { name: '' }});

    const update = yield Model.findById(doc._id);

    console.log(update); // does not have name property
  });
}

The mongoose debug log output:

Mongoose: models.insert({ name: 'Test', _id: ObjectId("58aa06a42b50f504015c86a3"), __v: 0 })
Mongoose: models.update({ _id: ObjectId("58aa06a42b50f504015c86a3") }, { '$unset': { name: 0 } }, {})
Mongoose: models.findOne({ _id: ObjectId("58aa06a42b50f504015c86a3") }, { fields: undefined })

Maybe it's an issue with your schema or how you're doing the update?

Are you sure you are using v4.8.3?
I tested this on other developer's machines too, anyhow i downgraded the version to 4.8.1.

@Harekam yeah i was. Do you have a better repro script where I can see the schema and maybe the context in which you're doing the $unset?

Hey @Harekam any update on this? Otherwise I'm going to close the issue soon as stale.

I just stumbled on a similar issue, leaving this in case it helps someone else. Mongoose will strip from $unset and $set any properties that is not defined in your schema. You can't explicitly $unset or $set a property that is not defined in your schema. In my case I was getting:

Error: { MongoError: exception: '$unset' is empty. You must specify a field like so: {$unset: {<field>: ...}}

Even though i did pass an object to $unset, Mongoose was stripping the property since it wasn't set in the schema.

I also experience the same issue on anything above 4.10.4. Haven't checked previous versions.

Code very similar to varunjayaraman errors out for me with ongoError: '$unset' is empty. You must specify a field like so: {$unset: {<field>: ...}} Only difference is I'm calling it on a discriminator model.update()

This is not working on Mongoose v5.6.9.

@mayconmesquita please open a separate issue and follow the issue template.

Was this page helpful?
0 / 5 - 0 ratings