Deprecation Warnings
There are several deprecations in the MongoDB Node.js driver that Mongoose users should be aware of. Mongoose provides options to work around these deprecation warnings, but you need to test whether these options cause any problems for your application. Please report any issues on GitHub.
Summary
To fix all deprecation warnings, follow the below steps:
mongoose.set('useNewUrlParser', true);
mongoose.set('useFindAndModify', false);
mongoose.set('useCreateIndex', true);
mongoose.set('useUnifiedTopology', true);
- Replace
update()
withupdateOne()
,updateMany()
, orreplaceOne()
- Replace
remove()
withdeleteOne()
ordeleteMany()
. - Replace
count()
withcountDocuments()
, unless you want to count how many documents are in the whole collection (no filter). In the latter case, useestimatedDocumentCount()
.
Read below for more a more detailed description of each deprecation warning.
The useNewUrlParser
Option
By default, mongoose.connect()
will print out the below warning:
DeprecationWarning: current URL string parser is deprecated, and will be
removed in a future version. To use the new parser, pass option
{ useNewUrlParser: true } to MongoClient.connect.
The MongoDB Node.js driver rewrote the tool it uses to parse MongoDB connection strings.
Because this is such a big change, they put the new connection string parser
behind a flag. To turn on this option, pass the useNewUrlParser
option to
mongoose.connect()
or mongoose.createConnection()
.
mongoose.connect(uri, { useNewUrlParser: true });
mongoose.createConnection(uri, { useNewUrlParser: true });
You can also set the global useNewUrlParser
option
to turn on useNewUrlParser
for every connection by default.
// Optional. Use this if you create a lot of connections and don't want
// to copy/paste `{ useNewUrlParser: true }`.
mongoose.set('useNewUrlParser', true);
To test your app with { useNewUrlParser: true }
, you only need to check
whether your app successfully connects. Once Mongoose has successfully
connected, the URL parser is no longer important. If you can't connect
with { useNewUrlParser: true }
, please open an issue on GitHub.
findAndModify()
If you use Model.findOneAndUpdate()
,
by default you'll see one of the below deprecation warnings.
DeprecationWarning: Mongoose: `findOneAndUpdate()` and `findOneAndDelete()` without the `useFindAndModify` option set to false are deprecated. See: https://mongoosejs.com/docs/5.x/docs/deprecations.html#findandmodify
DeprecationWarning: collection.findAndModify is deprecated. Use findOneAndUpdate, findOneAndReplace or findOneAndDelete instead.
Mongoose's findOneAndUpdate()
long pre-dates the MongoDB driver's findOneAndUpdate()
function, so it uses the MongoDB driver's findAndModify()
function
instead. You can opt in to using the MongoDB driver's findOneAndUpdate()
function using the useFindAndModify
global option.
// Make Mongoose use `findOneAndUpdate()`. Note that this option is `true`
// by default, you need to set it to false.
mongoose.set('useFindAndModify', false);
You can also configure useFindAndModify
by passing it through the connection options.
mongoose.connect(uri, { useFindAndModify: false });
This option affects the following model and query functions. There are no intentional backwards breaking changes, so you should be able to turn this option on without any code changes. If you discover any issues, please open an issue on GitHub.
Model.findByIdAndDelete()
Model.findByIdAndRemove()
Model.findByIdAndUpdate()
Model.findOneAndDelete()
Model.findOneAndRemove()
Model.findOneAndUpdate()
Query.findOneAndDelete()
Query.findOneAndRemove()
Query.findOneAndUpdate()
You can also safely ignore this warning. Mongoose will not remove the legacy useFindAndModify: true
behavior until Mongoose 6.0.
ensureIndex()
If you define indexes in your Mongoose schemas, you'll see the below deprecation warning.
DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes
instead.
By default, Mongoose 5.x calls the MongoDB driver's ensureIndex()
function.
The MongoDB driver deprecated this function in favor of createIndex()
.
Set the useCreateIndex
global option to opt in to making Mongoose use createIndex()
instead.
mongoose.set('useCreateIndex', true);
You can also configure useCreateIndex
by passing it through the connection options.
mongoose.connect(uri, { useCreateIndex: true });
There are no intentional backwards breaking changes with the useCreateIndex
option, so you should be able to turn
this option on without any code changes. If you discover any issues,
please open an issue on GitHub.
You can also safely ignore this warning. Mongoose will not remove the legacy useCreateIndex: false
behavior until Mongoose 6.0.
remove()
The MongoDB driver's remove()
function is deprecated in favor of deleteOne()
and deleteMany()
. This is to comply with
the MongoDB CRUD specification,
which aims to provide a consistent API for CRUD operations across all MongoDB
drivers.
DeprecationWarning: collection.remove is deprecated. Use deleteOne,
deleteMany, or bulkWrite instead.
To remove this deprecation warning, replace any usage of remove()
with
deleteMany()
, unless you specify the single
option to remove()
. The single
option limited remove()
to deleting at most one document, so you should
replace remove(filter, { single: true })
with deleteOne(filter)
.
// Replace this:
MyModel.remove({ foo: 'bar' });
// With this:
MyModel.deleteMany({ foo: 'bar' });
// Replace this:
MyModel.remove({ answer: 42 }, { single: true });
// With this:
MyModel.deleteOne({ answer: 42 });
useUnifiedTopology
By default, mongoose.connect()
will print out the below warning:
DeprecationWarning: current Server Discovery and Monitoring engine is
deprecated, and will be removed in a future version. To use the new Server
Discover and Monitoring engine, pass option { useUnifiedTopology: true } to
the MongoClient constructor.
Mongoose 5.7 uses MongoDB driver 3.3.x, which introduced a significant refactor of how it handles monitoring all the servers in a replica set or sharded cluster. In MongoDB parlance, this is known as server discovery and monitoring.
To opt in to using the new topology engine, use the below line:
mongoose.set('useUnifiedTopology', true);
The useUnifiedTopology
option removes support for several
connection options that are
no longer relevant with the new topology engine:
autoReconnect
reconnectTries
reconnectInterval
When you enable useUnifiedTopology
, please remove those options
from your mongoose.connect()
or
createConnection()
calls.
If you find any unexpected behavior, please open up an issue on GitHub.
update()
Like remove()
, the update()
function is deprecated in favor
of the more explicit updateOne()
, updateMany()
, and replaceOne()
functions. You should replace
update()
with updateOne()
, unless you use the multi
or overwrite
options.
collection.update is deprecated. Use updateOne, updateMany, or bulkWrite
instead.
// Replace this:
MyModel.update({ foo: 'bar' }, { answer: 42 });
// With this:
MyModel.updateOne({ foo: 'bar' }, { answer: 42 });
// If you use `overwrite: true`, you should use `replaceOne()` instead:
MyModel.update(filter, update, { overwrite: true });
// Replace with this:
MyModel.replaceOne(filter, update);
// If you use `multi: true`, you should use `updateMany()` instead:
MyModel.update(filter, update, { multi: true });
// Replace with this:
MyModel.updateMany(filter, update);
count()
The MongoDB server has deprecated the count()
function in favor of two
separate functions, countDocuments()
and
estimatedDocumentCount()
.
DeprecationWarning: collection.count is deprecated, and will be removed in a future version. Use collection.countDocuments or collection.estimatedDocumentCount instead
The difference between the two is countDocuments()
can accept a filter
parameter like find()
. The estimatedDocumentCount()
function is faster, but can only tell you the total number of documents in
a collection. You cannot pass a filter
to estimatedDocumentCount()
.
To migrate, replace count()
with countDocuments()
unless you do not
pass any arguments to count()
. If you use count()
to count all documents
in a collection as opposed to counting documents that match a query, use
estimatedDocumentCount()
instead of countDocuments()
.
// Replace this:
MyModel.count({ answer: 42 });
// With this:
MyModel.countDocuments({ answer: 42 });
// If you're counting all documents in the collection, use
// `estimatedDocumentCount()` instead.
MyModel.count();
// Replace with:
MyModel.estimatedDocumentCount();
// Replace this:
MyModel.find({ answer: 42 }).count().exec();
// With this:
MyModel.find({ answer: 42 }).countDocuments().exec();
// Replace this:
MyModel.find().count().exec();
// With this, since there's no filter
MyModel.find().estimatedDocumentCount().exec();
GridStore
If you're using gridfs-stream, you'll see the below deprecation warning:
DeprecationWarning: GridStore is deprecated, and will be removed in a
future version. Please use GridFSBucket instead.
That is because gridfs-stream relies on a deprecated MongoDB driver class. You should instead use the MongoDB driver's own streaming API.
// Replace this:
const conn = mongoose.createConnection('mongodb://localhost:27017/gfstest');
const gfs = require('gridfs-store')(conn.db);
const writeStream = gfs.createWriteStream({ filename: 'test.dat' });
// With this:
const conn = mongoose.createConnection('mongodb://localhost:27017/gfstest');
const gridFSBucket = new mongoose.mongo.GridFSBucket(conn.db);
const writeStream = gridFSBucket.openUploadStream('test.dat');