Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why am I getting this deprecated warning?! MongoDB

I'm working with MongoDB in NodeJS,

    const { MongoClient, ObjectId } = require("mongodb");

const MONGO_URI = `mongodb://xxx:xxx@xxx/?authSource=xxx`; // prettier-ignore

class MongoLib {

  constructor() {
    this.client = new MongoClient(MONGO_URI, {
      useNewUrlParser: true,
    });
    this.dbName = DB_NAME;
  }

  connect() {
    return new Promise((resolve, reject) => {
      this.client.connect(error => {
        if (error) {
          reject(error);
        }
        resolve(this.client.db(this.dbName));
      });
    });
  }
  async getUser(collection, username) {
    return this.connect().then(db => {
      return db
        .collection(collection)
        .find({ username })
        .toArray();
    });
  }
}

let c = new MongoLib();

c.getUser("users", "pepito").then(result => console.log(result));
c.getUser("users", "pepito").then(result => console.log(result));

and when the last c.getUser statement is executed (that's to say, when I make a SECOND connectio) Mongodb outputs this warning:

the options [servers] is not supported
the options [caseTranslate] is not supported
the options [username] is not supported
the server/replset/mongos/db options are deprecated, all their options are supported at the top level of the options object [poolSize,ssl,sslValidate,sslCA,sslCert,sslKey,sslPass,sslCRL,autoReconnect,noDelay,keepAlive,keepAliveInitialDelay,connectTimeoutMS,family,socketTimeoutMS,reconnectTries,reconnectInterval,ha,haInterval,replicaSet,secondaryAcceptableLatencyMS,acceptableLatencyMS,connectWithNoPrimary,authSource,w,wtimeout,j,forceServerObjectId,serializeFunctions,ignoreUndefined,raw,bufferMaxEntries,readPreference,pkFactory,promiseLibrary,readConcern,maxStalenessSeconds,loggerLevel,logger,promoteValues,promoteBuffers,promoteLongs,domainsEnabled,checkServerIdentity,validateOptions,appname,auth,user,password,authMechanism,compression,fsync,readPreferenceTags,numberOfRetries,auto_reconnect,minSize,monitorCommands,retryWrites,useNewUrlParser]

But I'm not using any deprecated options. Any ideas?


EDIT

After a little discussion with molank in the comments, it looks like open several connections from the same server is not a good practice, so maybe that's what the warning is trying to say (badly I think). So if you have the same problem, save the connection instead of the mongo client.

like image 843
Antonio Gamiz Delgado Avatar asked Feb 11 '19 21:02

Antonio Gamiz Delgado


2 Answers

Reposting from https://jira.mongodb.org/browse/NODE-1868:

The deprecation messages are likely because client.connect is being called multiple times. Overall, calling client.connect multiple times currently (as of driver v3.1.13) has undefined behavior, and it is not recommended. It is important to note that once the promise returned from connect resolves, the client remains connected until you call client.close:

const client = new MongoClient(...);

client.connect().then(() => {
  // client is now connected.
  return client.db('foo').collection('bar').insertOne({
}).then(() => {
  // client is still connected.

  return client.close();
}).then(() => {
  // client is no longer connected. attempting to use it will result in undefined behavior.
});

The client by default maintains multiple connections to each server it is connected to, and can be used for multiple simultaneous operations*. You should be fine running client.connect once, and then running your operations on the client object

* Note that the client is NOT thread-safe or fork-safe, so it cannot be shared across forks, and it not compatible with node's cluster or worker_threads modules.

like image 93
darpa Avatar answered Oct 21 '22 12:10

darpa


The function .connect() takes 3 arguments and is defined as such MongoClient.connect(url[, options], callback). So you need to provide an URL first, then the options and only then you give it the callback. Here is an example from the docs

MongoClient.connect("mongodb://localhost:27017/integration_tests", { native_parser: true }, function (err, db) {
    assert.equal(null, err);

    db.collection('mongoclient_test').update({ a: 1 }, { b: 1 }, { upsert: true }, function (err, result) {
        assert.equal(null, err);
        assert.equal(1, result);

        db.close();
    });
});

Another way to go, since you already created your MongoClient is to use .open instead. It only takes a callback, but you call it from the mongoClient you created (this.client). You ca use it like this

this.client.open(function(err, mongoclient) {
    // Do stuff
});

Note

Make sure you check out the MongoClient docs, you'll find a lot of good examples that may guide you even better.

like image 1
molamk Avatar answered Oct 21 '22 13:10

molamk