Mongoose: Docs page for how to fix deprecation warnings

Created on 27 Aug 2018  ·  31Comments  ·  Source: Automattic/mongoose

After #6917 it should now be possible to clear up all deprecation warnings by:

  • Replacing update() with updateOne(), updateMany(), or replaceOne()
  • Replacing remove() with deleteOne() or deleteMany()
  • Setting mongoose.set('useFindAndModify', false);
  • Setting mongoose.set('useCreateIndex', true);
  • Setting mongoose.set('useNewUrlParser', true);

Need a docs page to summarize this.

docs

Most helpful comment

I believe it is mongoose.set('useCreateIndex', true)

All 31 comments

If these are set, would it be incompatible with or breaking the current program?

@isLishude the only differences we are aware of are:

1) Support for MongoDB 3.0.x
2) updateOne() and updateMany() do not support the overwrite option. If you use update(filter, update, { overwrite: true }), you should use replaceOne(filter, update), not updateOne(filter, update, { overwrite: true })

If you run into any other problems, please don't hesitate to open up a GitHub issue.

I set mongoose.set('useCreateIndexes', true) and still get DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead.

I've tried it before and after mongoose.connect().

@ulrichb Are you sure that you're using [email protected] that released an hour ago?

I can replicate what @ulrichb is seeing on 5.2.10 with:

6922.js

#!/usr/bin/env node
'use strict';

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/test', { useNewUrlParser: true });
mongoose.set('useCreateIndexes', true);

const conn = mongoose.connection;
const Schema = mongoose.Schema;

const schema = new Schema({
  name: {
    type: String,
    unique: true
  }
});

const Test = mongoose.model('test', schema);

const test = new Test({ name: 'one' });

async function run() {
  console.log(`mongoose version: ${mongoose.version}`);
  await conn.dropDatabase();
  await test.save();
  return conn.close();
}

run();

Output:

issues: ./6922.js
mongoose version: 5.2.10
(node:7186) DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead.
issues:

I believe it is mongoose.set('useCreateIndex', true)

updated the original comment to reflect @saagar2000's observation. Thanks @saagar2000 !

@vkarpov15 is it possible to rename the document method remove to delete to be consistent as well? (Or provide an alias)?

Currently I'm refactoring all Model based usage of remove to deleteOne and deleteMany, but the document methods are still called remove() (which is also inconsistent with the isDeleted() method).

E.g.

const Foo = mongoose.model('Foo');
const foo = new Foo();
foo.remove(); //<-- create alias/rename to foo.delete()

I'm seeing the collection.{remove|update} is deprecated warning on Document.{remove|update} operations.

const doc = await model.findById(someId);
await doc.update({ $set: { someProp: true }}); // Deprecation warning
await doc.remove() // Deprecation warning

@adamreisnz yeah we should add an alias doc.delete(), ditto for doc.update() @mycompassspins

mongoose.set('useCreateIndex', true) has no affect for me. 😞
still getting the 'DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead.'

@ParikshitChavan Did you set this option before calling mongoose.model()?

Using mongoose 5.2.12. I also get this: the options [useCreateIndex] is not supported in addition to the deprecation warning.

More info: I only get this extra message when pass useCreateIndex as a connection option. When i use mongoose.set() I don't get that message.

looks like it should work properly when pass as connection option, but it doesn't. only after explicit mongoose.set()

@Fonger @govindrai
I tried doing this through connection options and though mongoose.set()
before and after connection to the DB.
the 'DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead.' always seems to persist.

Same here, cant get rid of collection.ensureIndex is deprecatedwarning ... No matter if use set or as an option...

@ParikshitChavan @govindrai @Avcajaraville

You have to put mongoose.set('useCreateIndex', true) before EVERY mongoose.model() call
(Note: not mongoose.connect() ).

See the discussion in #6890. This is fixed in 5.2.13 (but it's not released yet).

@Fonger @vkarpov15 after upgrade to 5.2.13 the issue still exists

(node:24769) DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead.

package.json:

"dependencies": {
        "bcrypt": "^3.0.0",
        "connect-mongo": "^2.0.1",
        "ejs": "^2.6.1",
        "express": "^4.16.3",
        "express-session": "^1.15.6",
        "mongodb": "^3.1.4",
        "mongoose": "^5.2.13",
        "morgan": "^1.9.0",
        "passport-local": "^1.0.0"
    },

node and npm info:

$ node -v
v10.6.0

$ npm -v
6.4.1

@arastu can you create a reproducible example with one or more files where you demonstrate that you are using 5.2.13 and are seeing one or more of these warnings?

Note that I am calling mongoose.set() before requiring my models

For Example:

index.js

#!/usr/bin/env node
'use strict';

const assert = require('assert');
const mongoose = require('mongoose');
mongoose.set('useCreateIndex', true);
mongoose.set('useFindAndModify', false);
mongoose.connect('mongodb://localhost:27017/test', { useNewUrlParser: true });
const conn = mongoose.connection;


const One = require('./one');
const Two = require('./two');

const one = new One({ name: '1' });
const two = new Two({ name: '2' });

async function run() {
  assert.strictEqual(mongoose.version, '5.2.13');
  await conn.dropDatabase();
  await Promise.all([One.init(), Two.init()]);
  await one.save();
  await two.save();
  await One.findOneAndUpdate({}, { name: 'one' });
  await Two.findOneAndUpdate({}, { name: 'two' });
  console.log(`${mongoose.version} should show no deprecations with the new settings.`);
  return conn.close();
}

run();

one.js

'use strict';

const mongoose = require('mongoose');

const schema = new mongoose.Schema({ name: { type: String, unique: true } });

module.exports = mongoose.model('one', schema);

two.js

'use strict';

const mongoose = require('mongoose');

const schema = new mongoose.Schema({ name: { type: String, unique: true } });

module.exports = mongoose.model('two', schema);

Output:

6922: ./index.js
5.2.13 should show no deprecations with the new settings.
6922:

working for me in 5.2.13. @lineus will useCreateIndex be supported as a connection option? Currently getting the options [useCreateIndex] is not supported

i.e.
mongoose.connect( process.env.MONGODB_URI, { useNewUrlParser: true, autoIndex: false, useCreateIndex: true, } )

@govindrai right now you should do mongoose.set('useCreateIndex', true) as specified in the deprecation warning docs. But we'll add that as well.

I've upgraded to 5.2.14 and am still seeing deprecation warnings that don't make sense. For instance, collection.update is deprecated . . . when I'm actually using document.update. Same for the remove method of both the model and the document. Switching to document.updateOne producesTypeError: document.updateOne is not a function. Am I missing something here?

@mycompassspins Did you track the stack producing the warning ?

For instance, in my case turns out the deprecation warning was happening due to connect mongo.

If you follow the above instructions, at least for me, all deprecation warning where gone :)

Here's the stack:

DeprecationWarning: collection.update is deprecated. Use updateOne, updateMany, or bulkWrite instead.
    at NativeCollection.(anonymous function) [as update] (/MyProject/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js:143:28)
    at NodeCollection.update (/MyProject/node_modules/mquery/lib/collection/node.js:66:19)
    at model.Query._updateThunk (/MyProject/node_modules/mongoose/lib/query.js:3233:23)
    at model.Query.Query._execUpdate (/MyProject/node_modules/mongoose/lib/query.js:3245:23)
    at process.nextTick (/MyProject/node_modules/kareem/index.js:333:33)
    at process._tickCallback (internal/process/next_tick.js:150:11)

Obviously, Model.update is actually executed, even though I'm calling MongooseDocument.update. This is what I'm doing, more or less:

async UpdateMyDocument(id:string, update:MyDocument):Promise<MyDocument>
{
    const doc = await MyModel.findById(id)
        .populate({ path: 'somePath', populate: [{ path: 'somePath.nested' }] });

    return await doc.update(update); // <= MongooseDocument.update is producing a Model.update deprecation warning
}

@mycompassspins are you sure you're on 5.2.14? We added doc.updateOne(update) in 5.2.13

There's an internal configuration typo in @5.2.16 that causes the deprecation notice for createIndexes to reemerge when you call createIndexes explicitly. PR opened☝️

(node:6455) DeprecationWarning: GridStore is deprecated, and will be removed in a future version. Please use GridFSBucket instead. What about this ??.
"gridfs-stream": "^1.1.1",
"mongoose": "^5.3.1",
"multer": "^1.4.0",
"multer-gridfs-storage": "^3.0.0"

@venkyyPoojari that's an old one, predates mongoose 5, but worth addressing. We will fix.

Thanks, I am going to use this for production, so please help as soon as possible

Thanks, I am going to use this for production, so please help as soon as possible

I have the same issue, I'm piping the readstream to the res object, is this what is wrong? I mean does it prevent the files to be read out?

@venkyyPoojari @romain10009 that's because gridfs-stream is out of date. The MongoDB driver has a new streaming API for GridFS that you should use instead: https://thecodebarbarian.com/mongodb-gridfs-stream

Was this page helpful?
0 / 5 - 0 ratings