Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecated collection methods from mongodb #6880

Closed
sam-caine opened this issue Aug 17, 2018 · 28 comments
Closed

Deprecated collection methods from mongodb #6880

sam-caine opened this issue Aug 17, 2018 · 28 comments
Milestone

Comments

@sam-caine
Copy link

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

Bug

What is the current behavior?

Model.findByIdAndUpdate() is issuing a deprecation warning for mongodb - which has deprecated collection.findAndModify. Mongodb suggests using findOneAndUpdate, findOneAndReplace or findOneAndDelete instead.

collection.ensureIndex is also deprecated - mongodb suggests using createIndexes instead.

If the current behavior is a bug, please provide the steps to reproduce.

Using Model.findByIdAndUpdate / findOneAndUpdate to alter a document returns these deprecation warnings.

What is the expected behavior?

No deprecation warnings!

Please mention your node.js, mongoose and MongoDB version.

Node v10.8.0
mongodb v3.6.2
mongoose v5.2.9

@ulrichb
Copy link

ulrichb commented Aug 17, 2018

Same here. I also get "find option [fields] is deprecated and will be removed in a later version."

@Agamnentzar
Copy link

(node:13076) DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead.
(node:13076) DeprecationWarning: collection.remove is deprecated. Use deleteOne, deleteMany, or bulkWrite instead.
(node:13076) DeprecationWarning: collection.find option [fields] is deprecated and will be removed in a later version.
(node:13076) DeprecationWarning: collection.update is deprecated. Use updateOne, updateMany, or bulkWrite instead.

Here's some other ones I got

@Fonger
Copy link
Contributor

Fonger commented Aug 17, 2018

Related to #6165 and can be reproduced on CI test

You can specify useFindAndModify to false to prevent partial deprecation message. IMO this should be default to false now.

mongoose.set('useFindAndModify', false);

Warning: Do not set this option to false in production without proper testing

However, other deprecated methods like ensureIndex(es) and update still need to be superseded with new API too. Setting this option to false won't fix this.
Maybe we need to update all deprecated method and remove useFindAndModify options in the next major release?

Note:
Only MongoDB 3.2+ support findOneAndUpdate series query but the underlying mongodb@3.1.3 library still use findAndModify polyfill to remain compatibility back to 2.6 so making useFindAndModify default to false won't actually drop support for MongoDB 3.0 currently.

However this compatibility definitely will break soon as they have been marked as deprecated since mongodb@2.1 (very long time ago) and now even throw warning messages.

Hence, I suggest next major release of mongoose (6.x) deprecate MongoDB 3.0 support and adopt all new API. Furthermore, MongoDB 3.0 has reached End-of-life in February, 2018, half of a year ago.

Any thoughts?

@imvasen
Copy link

imvasen commented Aug 17, 2018

So ... why is this happening? Is it necessary to wait until the next mongoose major release?

@Fonger
Copy link
Contributor

Fonger commented Aug 18, 2018

@lpiVasquez it's because the document says mongoose 5.x support MongoDB Server 3.0.

For now it’s safe to just use the new API because underlying API still handling this for us. However it won’t work once the underlying library change this behavior and we need to be very careful when upgrading the underlying library.

What I mean is not ignoring the issue but dropping support for MongoDB Server 3.0 in the next release 5.3. At least don’t break in 5.2. Just my opinion though.

@lineus
Copy link
Collaborator

lineus commented Aug 18, 2018

@IpiVasquez

if by,

why is this happening?

you mean,

why is mongodb deprecating these APIs

Mongodb has a plan in place to make the various driver APIs more consistent. This is documented here in the mongodb crud spec

Is it necessary to wait until the next mongoose major release?

If we stick to the semver spec, then anything that breaks the API should happen in a MAJOR release, like @6.0.0 as opposed to a minor release like @5.3.0 or a patch release like @5.2.10.

Looking back at the history of the native driver, I wouldn't expect them to remove these methods until v4 of the driver.

In the meantime, I think most of the deprecation warnings I've seen so far can be mitigated in userland by not calling deprecated methods. I'm guessing most of these methods will be removed in mongoose @6.0.0 anyway.

I think the 2 main issues for us to deal with in mongoose sooner rather than later are substituting projections for fields in query options ( works back to at least server version 3.0.15 ) and potentially changing the default value of useFindAndModify as described by @Fonger, with one addendum:

findOneAndUpdate in the native driver will call findAndModify for you internally ( without the deprecation warning ) when you're connected to a server pre 3.2, so findOneAndUpdate in mongoose still works with mongodb pre 3.2 and useFindAndModify: false as demonstrated in this example:

6880.js

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

const mongoose = require('mongoose');
mongoose.set('useFindAndModify', false);

const url = 'mongodb://localhost:27017/test';
const opts = { useNewUrlParser: true };

mongoose.connect(url, opts);
const conn = mongoose.connection;
const Schema = mongoose.Schema;

const schema = new Schema({
  name: String
});

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

async function run() {
  await conn.dropDatabase();
  let admin = conn.db.admin();
  let { version } = await admin.serverInfo();
  console.log(`mongodb: ${version}`);
  console.log(`mongoose: ${mongoose.version}`);

  let cond = {};
  let update = { name: 'Sarah' };
  let opts = {
    upsert: true,
    new: true
  };
  
  let sarah = await Test.findOneAndUpdate(cond, update, opts);
  console.log(sarah);
  return conn.close();
}

run();

Output:

issues: ./6880.js
mongodb: 3.0.15
mongoose: 5.2.9
{ _id: 5b779ca8d1326ce227b6869f, __v: 0, name: 'Sarah' }
issues:

You can also demonstrate this with just the native driver like this:

6880_native.js

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

const { MongoClient, Logger } = require('mongodb');

const uri = 'mongodb://localhost:27017/test';
const opts = { 
  useNewUrlParser: true
};

async function run() {
  const client = new MongoClient(uri, opts);
  await client.connect();
  const db = client.db('gh-6881');
  await db.dropDatabase().catch(handleError);

  Logger.setLevel('debug');
  let res = await db
    .collection('tests')
    .findOneAndUpdate({}, { $set: { name: 'michael' } }, { upsert: true })
    .catch(handleError);
  Logger.setLevel('error');
  console.log(res);
  let doc = await db
    .collection('tests')
    .findOne({})
    .catch(handleError);

  console.log(doc);
  process.exit(0);
}

run();

function handleError(e) {
  return console.error(e.message);
}

truncated Output:

...
message: 'executing command [{"ns":"gh-6881.$cmd","cmd":{"findAndModify":"tests","query":{},"new":false,"remove":false,"upsert":true,"update":{"$set":{"name":"michael"}}},"options":{}}] against localhost:27017',
...
{ value: null,
  lastErrorObject:
   { updatedExisting: false,
     n: 1,
     upserted: 5b77a23cd1326ce227b686a1 },
  ok: 1 }
{ _id: 5b77a23cd1326ce227b686a1, name: 'michael' }

@midrissi
Copy link

Same here. I got this warning on application start:

(node:9856) DeprecationWarning: collection.findAndModify is deprecated. Use findOneAndUpdate, findOneAndReplace or findOneAndDelete instead.
(node:9856) DeprecationWarning: collection.find option [fields] is deprecated and will be removed in a later version.
(node:9856) DeprecationWarning: collection.find option [fields] is deprecated and will be removed in a later version.

Fonger added a commit to Fonger/mongoose that referenced this issue Aug 18, 2018
`useFindAndModify` default to false now Automattic#6880
and make overwrite option compatibile to fixes Automattic#6887
@Fonger
Copy link
Contributor

Fonger commented Aug 18, 2018

If you find deprecation warning annoying, as a temporary workaround, you can start node.js process in cli with --no-deprecation to suppress the warning. It's not recommended to do so though.

@islishude
Copy link

with mine:

 (node:1) DeprecationWarning: collection.findAndModify is deprecated. Use findOneAndUpdate, findOneAndReplace or findOneAndDelete instead.
 (node:1) DeprecationWarning: collection.remove is deprecated. Use deleteOne, deleteMany, or bulkWrite instead.
(node:1) DeprecationWarning: collection.update is deprecated. Use updateOne, updateMany, or bulkWrite instead.
 (node:1) DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead.
(node:1) DeprecationWarning: collection.find option [fields] is deprecated and will be removed in a later version.
(node:1) DeprecationWarning: collection.find option [fields] is deprecated and will be removed in a later version.

love package-lock.json more than ever...

@vkarpov15 vkarpov15 added this to the 5.2.10 milestone Aug 19, 2018
@vkarpov15
Copy link
Collaborator

There are several workarounds to get around these deprecation warnings:

  1. Re: findOneAndUpdate() and findAndModify() deprecation, use mongoose.set('useFindAndModify', false);
  2. Re: remove() deprecation, switch to using deleteOne() or deleteMany() depending on if you only want to delete one doc
  3. Re: update() deprecation, replace with updateMany()

We'll add some docs to help people clean up these deprecation warnings, and make some internal changes so mongoose doesn't cause one of these deprecation warnings.

@adamreisnz
Copy link
Contributor

Maybe we need to update all deprecated method and remove useFindAndModify options in the next major release?

I'd be in favour of this 👍

Does mongoose already have support for the new methods, deleteOne(), deleteMany(), updateMany() etc?

@FIRAT-URASLI
Copy link

FIRAT-URASLI commented Aug 20, 2018

+1
same warning. we need to wait for new driver.

@joffarex
Copy link

so like, right now we have to ignore those warnings? i mean i am trying to create api, where i need to get everything from db and whenever i call collection.find().then()....etc it gives me same warning. what can i do to replace that find() method?

@adamreisnz
Copy link
Contributor

adamreisnz commented Aug 22, 2018

If you're just bothered by the warnings, you can probably disable deprecation notices in Node (see Fonger's comment above), or you can revert back to an older version of Mongoose.

vkarpov15 added a commit to mongoosejs/mquery that referenced this issue Aug 22, 2018
vkarpov15 added a commit to mongoosejs/mquery that referenced this issue Aug 22, 2018
@PetrVasilev
Copy link

So what I need to do?

@Ben4code
Copy link

Got this warning message from mongoose each time i run a find query. Going to ignore it till after the next update from the mongoose team.

(node:15500) DeprecationWarning: collection.find option [fields] is deprecated and will be removed in a later version.

@vkarpov15
Copy link
Collaborator

The fix for the fields deprecation warning will be in 5.2.10, you won't see it anymore. To clean up the other deprecation warnings, follow the instructions in this comment: #6922 (comment)

@gianpaj
Copy link
Contributor

gianpaj commented Sep 23, 2018

Thanks for writing this doc https://mongoosejs.com/docs/deprecations.html

Re: findOneAndUpdate() and findAndModify() deprecation, the only current (5.2.17) workaround is to set:

mongoose.set('useFindAndModify', false);

is that true?

I'm using Model.findByIdAndUpdate() and Model.findOneAndUpdate()

I assume the underlying mongo db driver functions being used by mongoose will be / should be updated at some point.
Would be I be right?

@daniyalawan
Copy link

+1 I am having same deprecation warning for using Model.findByIdAndUpdate();

I am using following verisions:

  • mongodb: 3.1.4
  • mongoose: 5.2.16

@0xAnakin
Copy link

Any news on this ?

@lineus
Copy link
Collaborator

lineus commented Sep 26, 2018

@gianpaj yes mongoose.set('useFindAndModify', false) is the only current workaround for the findAndModify deprecation warning. My guess is that the underlying call to collection.findAndModify() will go away in mongoose@6.0.0. @vkarpov15 does that sound about right? or is it too early to commit to a time frame?

@daniyalawan check out the docs here the 'useFindAndModify' option applies to you if you call findOneAndUpdate in your code ( this extends to findByIdAndUpdate because it calls findOneAndUpdate internally ).

@Sastidar what issue(s) are you having after upgrading to mongoose@5.2.17? All deprecation warnings should be addressed in these docs

@vkarpov15
Copy link
Collaborator

@lineus @gianpaj yep the need for the useFindAndModify option will go away with Mongoose 6.0.0. No timeframe for when we will release Mongoose 6.

@LBWright
Copy link

Regarding the deprecation warning - Will mongoose be phasing out the ability to use the findByIdAndUpdate method or will the underlying findAndModify just be phased out without killing my implementation?

I'm basically asking if I change all of my findByIdAndUpdate to findOneAndUpdate before I have a larger codebase.

cklanac added a commit to cklanac/noteful-app-v4 that referenced this issue Oct 29, 2018
@ankitsny
Copy link

@gianpaj yes mongoose.set('useFindAndModify', false) is the only current workaround for the findAndModify deprecation warning. My guess is that the underlying call to collection.findAndModify() will go away in mongoose@6.0.0. @vkarpov15 does that sound about right? or is it too early to commit to a time frame?

@daniyalawan check out the docs here the 'useFindAndModify' option applies to you if you call findOneAndUpdate in your code ( this extends to findByIdAndUpdate because it calls findOneAndUpdate internally ).

@Sastidar what issue(s) are you having after upgrading to mongoose@5.2.17? All deprecation warnings should be addressed in these docs

{new: true} will not work if i use mongoose.set('useFindAndModify', false). any other option?

@lineus
Copy link
Collaborator

lineus commented Oct 30, 2018

@anks333 the following example works for me. Can you modify it to show { new: true } not working?

6880.js

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

const assert = require('assert');
const mongoose = require('mongoose');
mongoose.set('useFindAndModify', false);
const { Schema, connection} = mongoose;
const DB = '6880';
const URI = `mongodb://localhost:27017/${DB}`;
const OPTS = { family: 4, useNewUrlParser: true };

const schema = new Schema({
  name: String
});

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

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

async function run() {
  await mongoose.connect(URI, OPTS);
  await connection.dropDatabase();
  const doc = await Test.create(test);
  assert.ok(doc);
  const cond = {};
  const update = { name: 'test2' };
  const options = { new: true };
  const updated = await Test.findOneAndUpdate(cond, update, options);
  assert.strictEqual(updated.name, 'test2');
  console.log('All Assertions Pass.');
  await connection.close();
}

run();

Output:

issues: ./6880.js
All Assertions Pass.
issues:

@vkarpov15
Copy link
Collaborator

@LBWright we have no intention of dropping support for findByIdAndUpdate, we will just swap out the underlying findAndModify without breaking the API

@jonaspereirar
Copy link

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

@vkarpov15
Copy link
Collaborator

@Automattic Automattic locked as resolved and limited conversation to collaborators Apr 9, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests