Mongoose: 弃用警告:`open()` 在 mongoose >= 4.11.0 中已弃用,请改用`openUri()`

创建于 2017-06-25  ·  158评论  ·  资料来源: Automattic/mongoose

弃用警告: open()在 mongoose >= 4.11.0 中已弃用,请改用openUri() ,如果使用connect()createConnection() ,请设置useMongoClient选项createConnection()

猫鼬 4.11.0、MongoDB 2.2.29、NodeJS 8.1.2

最有用的评论

最简单的解决方法; " npm remove mongoose " 然后 " npm install [email protected] --save " 问题解决了。 升级并不总是最好的选择。

所有158条评论

+1,我不知道在哪里解决这个警告

当连接字符串具有副本集时,警告实际上是针对 Mongoose 内部的代码:

Mongoose.prototype.connect = function() {
  var conn = this.connection;
  if ((arguments.length === 2 || arguments.length === 3) &&
      typeof arguments[0] === 'string' &&
      typeof arguments[1] === 'object' &&
      arguments[1].useMongoClient === true) {
    return conn.openUri(arguments[0], arguments[1], arguments[2]);
  }
  if (rgxReplSet.test(arguments[0]) || checkReplicaSetInUri(arguments[0])) {
    return new MongooseThenable(this, conn.openSet.apply(conn, arguments));
  }

  return new MongooseThenable(this, conn.open.apply(conn, arguments));
};

@tinovyatkin

那么,这是一个错误吗?

看起来像一个错误,我们可以通过在选项中添加useMongoClient: true来解决问题吗(您可能会看到 MongoDB 驱动程序弃用但不会抛出)

添加useMongoClient: true会使消息消失,但随后我的文档就会停止加载。 没有更深入地调试它,但我更愿意在调整我的代码之前先听听最佳实践。

我的应用程序也不适用于上面建议的解决方法。 它根本不再运行 MyModel.find 方法,并且没有给出错误和超时。

“useMongoclient:true”选项在大多数情况下不起作用的原因是该选项,每个与 mongoose 连接相关的对象都返回虚拟对象导致无法访问 mongodb

我试着像这样使用它

const server = express();
mongoose.connect('mongodb://localhost/advisorDemoTestDB', { useMongoClient: true })
    .then(() => require('./db-init')(server))
    .catch(err => console.error(err));

但它不起作用

有同样的问题,即使没有副本集。

有同样的问题:

(node:4138) DeprecationWarning: `open()` is deprecated in mongoose >= 4.11.0,
 use `openUri()` instead, or set the `useMongoClient` option if using `connect()` 
or `createConnection()`

相同的...

在我将以下代码添加到我的 mongo 连接后,我现在无法查询任何内容。
{useMongoClient: true}。
任何建议将不胜感激!!

+1 与副本集相同,无分片

+1

+1

+1

+1

+1

+1

+1

最简单的解决方法; " npm remove mongoose " 然后 " npm install [email protected] --save " 问题解决了。 升级并不总是最好的选择。

+1

+1

我收到 2 条消息:

(node:9260) DeprecationWarning: `open()` is deprecated in mongoose >= 4.11.0,
use `openUri()` instead, or set the `useMongoClient` option if using `connect()`
or `createConnection()`

Server started on port 3000

Db.prototype.authenticate method will no longer be available in the next major
release 3.x as MongoDB 3.6 will only allow auth against users in the admin db
and will no longer allow multiple credentials on a socket. Please authenticate
using MongoClient.connect with auth credentials.

第一个错误出现在 4.11.0 中。 第二个错误也出现在之前版本的 Mongoose 中。

plhosk,第二个应该在 4.11 中修复,但看起来它仍然存在,对我来说也是如此。

+1

可悲的是+1。

安装 4.10.8 没有问题。 请考虑将npm install mongoose --save更改为默认为 4.10.8,直到 11 稳定。

+1

+1

+1

+1

我也发现了这个问题。
__节点版本__:v6.10.0

__MongoDB__ emvironment:(我在最新版本的Mongo docker容器上运行)

2017-06-20T08:04:24.509+0000 I CONTROL  [initandlisten] db version v3.4.5
2017-06-20T08:04:24.509+0000 I CONTROL  [initandlisten] git version: 520b8f3092c48d934f0cd78ab5f40fe594f96863
2017-06-20T08:04:24.509+0000 I CONTROL  [initandlisten] OpenSSL version: OpenSSL 1.0.1t  3 May 2016
2017-06-20T08:04:24.509+0000 I CONTROL  [initandlisten] allocator: tcmalloc
2017-06-20T08:04:24.509+0000 I CONTROL  [initandlisten] modules: none
2017-06-20T08:04:24.509+0000 I CONTROL  [initandlisten] build environment:
2017-06-20T08:04:24.509+0000 I CONTROL  [initandlisten]     distmod: debian81
2017-06-20T08:04:24.509+0000 I CONTROL  [initandlisten]     distarch: x86_64
2017-06-20T08:04:24.509+0000 I CONTROL  [initandlisten]     target_arch: x86_64
2017-06-20T08:04:24.509+0000 I CONTROL  [initandlisten] options: { security: { authorization: "enabled" } }

我的连接配置:

var dbURL = `mongodb://${dbHost}:${dbPort}/${dbName}?authSource=admin`;
var dbAuth = { 
    useMongoClient: false
    user: dbUser,
    pass: dbPass
}
mongoose.connect(dbURL, dbAuth);

当我使用useMongoClient为假时。 Mongoose 显示以下警告:

(node:7868) DeprecationWarning: `open()` is deprecated in mongoose >= 4.11.0, use `openUri()` instead, or set the `useMongoClient` option if using `connect()` or `createConnection()`
Express server listening on port 3222 in development mode
Db.prototype.authenticate method will no longer be available in the next major release 3.x as MongoDB 3.6 will only allow auth against users in the admin db and will no longer allow multiple credentials on a socket. Please authenticate u
sing MongoClient.connect with auth credentials.

但它工作得很好。

但是,当我将其设置为true时,我发现了这个错误:

Unhandled rejection MongoError: not authorized on users to execute command { listIndexes: "sessions", cursor: {} }
    at Function.MongoError.create (<my project path>\node_modules\mongoose\node_modules\mongodb-core\lib\error.js:31:11)
    at queryCallback (<my project path>\node_modules\mongoose\node_modules\mongodb-core\lib\cursor.js:212:36)
    at <my project path>\node_modules\mongoose\node_modules\mongodb-core\lib\connection\pool.js:469:18
    at _combinedTickCallback (internal/process/next_tick.js:67:7)
    at process._tickCallback (internal/process/next_tick.js:98:9)

我也尝试从连接 URL 中删除authSource=admin ,但它仍然不起作用

(node:451) DeprecationWarning: open()在 mongoose >= 4.11.0 中已弃用,请使用
改为openUri() ,如果使用connect() createConnection() ,则设置useMongoClient选项
db.prototype.authenticate 方法将在下一个主要版本中不再可用
租赁 3.x 作为 MongoDB 3.6 将只允许对 admin db 和 w 中的用户进行身份验证
ill 不再允许在一个套接字上使用多个凭据。 请使用 M 进行身份验证
ongoClient.connect 与身份验证凭据。

我在 mongoose 版本 4.11.0 和 MongoDB 版本 3.4.5 中遇到了这个问题

+1

+1

采用

mongoose.createConnection(URI)

@nandofalcao使用时:

  • 猫鼬.createConnection (URI);
  • mongoose.connect (URI, {useMongoClient: true});

显然我无法保存新记录。

let userSchema = mongoose.Schema({ name: String });
let User = mongoose.model('User', userSchema);
let joao = new User({ name: 'NewJoao ' });
joao.save((err) => err ? throw err : console.log('User created!'));//nothing happens

今晚添加多语种并 +1 体验这一点。

// Load Mongoose
const mongoose = require('mongoose');
// import mongoose from 'mongoose' didn't give access to .connect()

// Use native Promises
mongoose.Promise = global.Promise;

// Connect database
export const Mongoose = new Promise((resolve, reject) => {
  const uri = `mongodb://${Singleton.currentConfig.databases.mongodb.host}/${Singleton.currentConfig.databases.mongodb.database}`;

  const options = {
    user: Singleton.currentConfig.databases.mongodb.user,
    pass: Singleton.currentConfig.databases.mongodb.password,
    server: {
      reconnectTries: Singleton.currentConfig.databases.mongodb.reconnectTries,
      reconnectInterval: Singleton.currentConfig.databases.mongodb.reconnectInterval,
      socketOptions: {
        keepAlive: Singleton.currentConfig.databases.mongodb.keepAlive,
        connectTimeoutMS: Singleton.currentConfig.databases.mongodb.connectTimeoutMS
      },
    },
  };

  // Initiate document store
  mongoose.connect(uri, options)

  // Check for anomalies
  .then((connected) => {
    if (mongoose.connection.readyState !== 1) {
      reject(connected);
    }
    resolve(connected);
  })

  // Complete meltdown
  .catch((error) => {
    console.log(`MongoDB Connection Error: ${error}`);
    process.exit(0);
  });
});

+1

我收到第二条消息:

[2017-06-27 16:14:23.702] [INFO] :: - 服务器在端口 2000 中启动

(node:1193) DeprecationWarning: open()在 mongoose >= 4.11.0 中已弃用,请改用openUri() ,或者如果使用connect()则设置useMongoClient选项或createConnection()

Db.prototype.authenticate 方法将在下一个主要版本 3.x 中不再可用,因为 MongoDB 3.6 将仅允许对 admin db 中的用户进行身份验证,并且不再允许在套接字上使用多个凭据。 请使用带有身份验证凭据的 MongoClient.connect 进行身份验证。

+1

+1

+1

+1

+1

有人可以锁定它以防止无用的 +1 吗?

出于对本主题订阅者的礼貌,请停止回复 +1,因为它会生成无用的电子邮件通知。 这不是一个论坛。 如果您想关注此主题,请使用右侧边栏上的订阅按钮。 您也可以自己做一些研究并提供解决方案。

我将版本改回 4.10.8,现在可以正常工作了。

看起来 ValYouW 有一个潜在的解决文档加载问题的方法:#5404

mongoose.connection.openUri('mongodb://127.0.0.1/camp_v12')

有人试过吗? 当我使用它时,我不推荐使用的警告消失了,它来自文档

http://mongoosejs.com/docs/connections.html

@crisamdegracia假设您已经建立了连接

// Or, if you already have a connection
connection.openUri('mongodb://localhost/myapp', { /* options */ });

我们没有(至少是我,因为我曾经使用 mongoose.connect 方法连接到 mongodb)

mongoose.connect(config.get('mongo'), {
  useMongoClient: true,
});

我找不到任何文件... 怎么了?

+1

因此,在查看了来自@phased90的链接问题后,该问题解释了您可以像这样连接:

const mongoose = require('mongoose');

mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost/test', {useMongoClient: true})
    .then(() => {
        let Cat = mongoose.model('Cat', {name: String});
        let kitty = new Cat({name: 'Zildjian'});

        kitty.save(err => {
            if (err) {
                console.log(err);
            } else {
                console.log('meow');
            }
        });
    })
    .catch(err => console.error(err));

我快速浏览了代码,似乎 4.11 返回MongooseThenable ,但提供了{useMongoClient: true}选项时除外。 在这种情况下,它调用Connection.prototype.openUri ,它返回一个新的Promise.ES6实例。 该Connection.prototype.openUri调用是否应该包含在MongooseThenable中?

我为这个问题道歉,这是我第一次看这个代码库,所以我有点不确定。 但是,如果我能澄清一下Moongoose.prototype.connect是否应该始终返回MongooseThenable的实例,我会很乐意尝试并帮助提供修复。

请注意,使用{useMongoClient: true}将导致Connection.prototype.openUri被调用,这不会触发由于 #5404 而在连接数据库之前创建的缓冲命令

+1

对不起,事情已经很疯狂了,一会儿看看。

@varunjayaraman无需抱歉,伙计。 人们可以等待,也可以尝试自己修复。

+1

因此,对于打开的实际问题,弃用警告不是错误,它只是一个警告:猫鼬将弃用其当前的连接逻辑,因此您应该传入useMongoClient参数。 这可以在文档中找到

在单独的说明中,这看起来是一个向后的突破性变化,希望这可以在下一个小版本中修复(或者可能不是,我在这里运行的睡眠很少):

这通常可以工作(除了useMongoClient部分,这是新的):

const mongoose = require('mongoose');
const co = require('co');
mongoose.Promise = global.Promise;
const GITHUB_ISSUE = `gh-5399`


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


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


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

这似乎给我一个错误,因为db.model不再是一个函数。

使用mongoose.model时,它可以工作:

const mongoose = require('mongoose');
const co = require('co');
mongoose.Promise = global.Promise;
const GITHUB_ISSUE = `gh-5399`


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


function exec() {
  return co(function* () {
    const db = mongoose.connect(`mongodb://localhost:27017/${GITHUB_ISSUE}`, { useMongoClient: true })

    return db
      .then(() => {
        const schema = new mongoose.Schema({
          name: String
        });


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

        return Model.create({ name: 'test' });
      })
      .then(doc => console.log(doc));

  });
}

@varunjayaraman我刚刚更新了 Mongoose 并按照您的建议使用useMongoClient: true ,但我有一个问题。
根据官方 Mongoose 文档,它不支持userpass选项:

the options [user] is not supported
the options [pass] is not supported

而且,是的,未能进行身份验证。 :-1:

我将尝试添加用户并传入连接字符串。
当我将用户名和密码添加到连接字符串中时它会起作用。 也许您应该更新文档。 😐

@itpcc尝试使用4.10.8版本是目前最好的解决方案。

npm remove mongoose
npm install [email protected] --save

信用: @ Chenz62

@CQBinh谢谢你的建议。 我已经阅读了有关它的评论。
但是,我不认为使用旧版本是目前最好的解决方案。 它可以通过插入连接字符串来解决。
我只是感到困惑,因为它在文档中提到但它不起作用。 :/
顺便说一句,我在这里报告为一个新问题

@varunjayaraman如果db.model不再存在,如何处理不同型号的多个不同猫鼬连接?

例如,model1 和 model2 附加到 mongooseConnection1,model3 和 model4 附加到 mongooseConnection2。

以前,这是通过为每个连接调用mongoose.createConnection并将模型附加到每个返回值来完成的。

编辑:或者在这种情况下它仍然有效:

const conn = mongoose.createConnection(...);
const Model = conn.model('ModelName', schema);

+1

@boyce-ywr 说真的,另一个+1??? 你们这些人怎么了??
发表建设性的评论,而不是那样的东西。

关于猫鼬,我不清楚mongoose.connect()方法是否会在未来的版本中被替换。 有人可以解释一下吗?

@simonemazzoni你是对的,他们在向我们发送垃圾邮件。

如果你想被包含在这个线程的通知中,你需要做的就是订阅它(线程顶部有一个按钮),

当你+1时,你所做的就是向这里的每个人发送一封电子邮件,说

你好我来了!

我们不在乎,我们正在等待建设性的意见解决方案

另外,为什么你们所有人都不 +1 将您的帖子从该列表中删除,它们是令人眼花缭乱的,并且在后方很痛苦,必须滚动过去才能获得真正的评论。

就像之前有人说的,唯一的“解决方案”就是回到[email protected]_ ...
至少现在!

貌似是bug,回[email protected]解决问题

使用 mongoose.createConnection(...) 而不是 mongoose.connect(...)

这是基于@diegoazh的推荐使用[email protected]的完整工作示例

const mongoose = require('mongoose')
mongoose.Promise = require('bluebird')  // optional, use this to get rid of 
                                        // the mpromise DeprecationWarning
const conn = mongoose.createConnection('mongodb://localhost/testDB')
const Schema = mongoose.Schema

const UserSchema = new Schema({
    username: String,
    email: String
})

const User = conn.model('User', UserSchema)
module.exports = User

@midnightcodr所以我们只是放弃连接并使用 createConnection 代替?

@bertolo1988就像 ppl 在这个问题上建议的那样,目前有两种解决方法

  1. 回退到 4.10.8
  2. 如果您想坚持使用新版本,请使用新模式
const conn = mongoose.createConnection(...)
const Model = conn.model(...)

我个人更喜欢第二种解决方案。

谢谢!!!
由 createConnection 解决,并使用该连接制作模型(而不是 mongoose)

let mongoose = require('mongoose');

mongoose.Promise = global.Promise;

module.exports = mongoose;
const mongoose = require('./set-mongoose');
module.exports = mongoose.createConnection('mongodb://localhost/advisorDemoTestDB');

新的连接模式需要一些代码更改,并且取决于项目的大小,这可能意味着大量时间甚至架构更改(考虑到创建模型需要连接的事实)。

如果旧的连接模型可以包装新的连接模型,那就太好了。

帖子很多,我可以尝试总结一下:

  1. 该警告是一个已弃用的警告,意思是,不要急于求成。 如果我们不改变任何东西,它仍然会像往常一样工作,一切似乎都很好

  2. 根据警告, connect() 将/已被修改,并且必须传递 useMongoClient 。 但这是可能的错误/问题

  • connect('myurl', {useMongoClient: true}) => 文档停止加载,无法写入数据库

  • connect('myurl', {useMongoClient: false}) => 似乎工作正常,但仍显示警告

因此这个问题的目的是在调用connect方法的情况下更正useMongoClient的使用。

同意?

尽管如此,虽然弃用警告确实是“只是”警告,但它的出现让我想知道它什么时候会真正被删除。 如果 mongoose 遵循 semver,它应该仍然存在于 4.x 分支中。 因此,在 5.x 发布之前,它仍应具有向后兼容性。

关于更改本身,除了更改日志中提到的更改之外,我无法快速找到有关此更改的任何内容,这有点烦人。 即使你确实改变了它,东西仍然会中断,据这里的多人说,这是因为.model()调用。

此外,即使是文档仍然显示mongoose.connect()mongoose.model() ,这使得这件事更加混乱。 mongoose.connect()更改仅在连接池下提及,本页其他部分未提及。 所以问题仍然存在,这是一个错误还是有意的?

我不知道这是怎么回事,但我在这个周末的大部分时间里都在尝试连接到 MongoDB 的 Atlas。 本机 mongodb 驱动程序立即启动并运行 CRUD 内容。

然而,试图让猫鼬继续前进是一场噩梦。 如果我将 createConnection 与 4.11 一起使用,则集群连接会被终止:

MongoError: connection 4 to cluster0-myshard.mongodb.net:27017 closed

或者,我可以设置

useMongoClient: true

但后来我在 connection.model 上未定义

<info> atlas-api-test.js:65 (Test.testVendors) conn.model undefined

@Archomeda没有计划删除 4.x 中的旧连接行为,并且 5.x 在使新连接逻辑达到稳定状态时被阻止。 连接文档中有 4.11.1 将改进的文档,链接到该文档应该会有所帮助。 回复: model()调用,如果您指定useMongoClient: truecreateConnection()不会返回连接,而是会解析为您需要.then()的连接的承诺https ://github.com/Automattic/mongoose/issues/5404#issuecomment -312522539 请随时就问题 #5404 提出任何疑虑。

@mkastner看起来您正在使用createConnection() 。 使用useMongoClient: truecreateConnection()返回一个解析为连接的承诺。 请使用await mongoose.createConnection()mongoose.createConnection().then()

@peterpeterparker #5404 指出将在 4.11.1 中修复的新连接逻辑的问题,将在接下来的 24 小时内发布。

@cosminn777你有什么架构问题? 请打开一个单独的问题来讨论它们。 长期计划是在 5.x 中我们将不支持 Node < 4,因此使用 mongoose 的每个人都将拥有对生成器和/或 async/await 的本地访问权限,因此这种更改就像添加yield一样简单await语句。

@alanpurple您所指的问题与提到的 #5404 相同,将在 4.11.1 中修复。

@itpcc我打开了一个单独的问题来跟踪 #5432。 现在,请将您的用户名/密码放在 URI 中: var dbURL = mongodb://${dbUser}:${dbPass}@${dbHost}:${dbPort}/${dbName}?authSource=管理员`。

总的来说,感谢大家耐心尝试这种新行为。 我意识到切换会引起一些头痛,这就是为什么我们将这种行为隐藏在标志后面的原因,但是 MongoDB 3.6 的一些变化需要彻底检查 mongoose 的内部连接逻辑。 我希望新的连接逻辑从长远来看会减少特定于猫鼬的连接错误,但请耐心等待我们解决行为和文档。 非常感谢您的反馈。

只要您在 4.x 上,您当前的连接逻辑就可以工作,它只会打印一个警告。 同时,请随时在单独的 github 问题中报告您遇到的任何问题。

刚刚采用了新方法,效果很好。 感谢大家!

@vkarpov15感谢您的澄清。

作为仅供参考, openSet也会引发相同的弃用警告(我使用的是副本集)。

总而言之,暂时忽略这个警告是安全的,因为它只与 Mongoose 的内部工作有关,我们可以尝试使用useMongoClient ,但还没有必要。

你认为它有多稳定? 使用安全吗? 我不想花 2 个小时重构我们所有的模型和连接逻辑来发现它在生产中仍然无法使用。

是否有可能删除弃用警告,直到使用标志稳定并且推荐的连接方式继续前进? 还是已经达到了这一点?

@vkarpov15

但我在createConnection 上使用异步。 我已经针对数据库服务器设置了两个测试。 第一个是本地 mongo-js 金丝雀测试,以确保 url 有效并且我可以读写:

tape('test connection via mongo native', async function testMongoConnection(t) {

  try {

    t.plan(1);
    let db = await MongoClient.connect(dbURL);
    await db.collection('users').insert({name: 'username'});
    let result = await db.collection('users').find({});
    let docs = await result.toArray();
    log.info('result', await result.toArray());
    t.equal(1, docs.length);
    db.collection('users').remove({});

    await db.close();

  } catch (err) {
  console.error(err)
  }
});

结果:

2017-07-04T09:00:34+0200 <info> atlas-api-test.js:28 (Test.testMongoConnection) result [ { _id: 595b3d1146734207bad88f9d, name: 'username' } ]
✔ should be equal

使用 mongoose createConnection 和 await 的 mongoose 测试成功:

tape('test connection via mongoose', async function testMongooseConnection(t) {

  try {
      let conn = await mongoose.createConnection(dbURL, {
        useMongoClient: true,
        /*
        // tried these settings too
        user: 'myUserName',
        pass: 'myPassword',
        connectTimeoutMS: 30000,
        rs_name: 'myReplSetName',
        ssl: true,
        auto_reconnect: true,
        */
      });

      let UserSchema = new mongoose.Schema({
        name: String,
      });

      let User = mongoose.model('User', UserSchema);
      let newUser = new User({name: 'username'});
      let createdUser = await newUser.save();

      // just ending test without validating any results
      t.end();

  } catch (err) {
    log.error(err);
  }

});

它会引发以下错误:

/mypath/node_modules/mongodb/lib/replset.js:390 process.nextTick(function() { throw err; })
                                    ^
MongoError: connection 8 to cluster0-shard-00-02-c4nst.domain.com:27017 closed at Function.MongoError.create (/mypath/node_modules/mongodb-core/lib/error.js:29:11)
at Socket.<anonymous> (/mypath/node_modules/mongodb-core/lib/connection/connection.js:202:22)
at Object.onceWrapper (events.js:316:30)
at emitOne (events.js:115:13)
at Socket.emit (events.js:210:7)
at TCP._handle.close [as _onclose] (net.js:549:12)`

我在这里可能大错特错,但对我来说,这看起来不像是异步/承诺问题;

我正在使用 Mongo Atlas。 当我使用 {useMongoClient: true} 时,我的应用程序将成功连接到数据库,但数据库对应用程序没有响应,对吧?

我的代码:
mongoose.connect(config.dbhost, {useMongoClient: true}, function(err){ if(err){ console.log(err); } else { console.log('connected to the database successfuly.'); } });

只是给大家一个通知,因为我没有看到这里提到它:4.11.1 已经发布,快速浏览后似乎使用 useMongoClient=true 时的缓冲问题已经修复。 明天我会测试更多。 还有谁?

最终的解决方案是什么?

这对我有用(v.4.11.1):

数据库.js

mongoose.connect(databaseUri, { useMongoClient: true })
      .then(() => console.log(`Database connected at ${databaseUri}`))
      .catch(err => console.log(`Database connection error: ${err.message}`));

用户模型.js

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const userSchema = new Schema({ ... });
const User = mongoose.connection.model('User', userSchema);

更新

初始化模型时可能不需要引用连接(感谢@kyrylkov @peterpeterparker):

用户模型.js

const User = mongoose.model('User', userSchema);

有人可以简要解释一下 { useMongoClient: true } 到底是什么,或者那个标志有什么作用?

我有点迷茫,使用它有什么好处?

我的意思是,就像我之前说的,我可以忍受这个警告,因此我不急于添加这个参数。
在文档中没有找到那么多,谢谢提前清理。

@Blackbaud-SteveBrush 它不起作用。 我正在使用 Mongo Atlas。 为什么它不起作用?

@Thinkdiff

不行怎么办? 它通常适用于我们在 mLab 和 MongoDB Atlas 上:

const User = mongoose.model('User', userSchema);

代替:

const User = mongoose.connection.model('User', userSchema);

如果我尝试使用 URI 中定义的少数主机启用 useMongoClient 选项,它会挂起然后抛出错误:
MongoError: no mongos proxy available at Timeout._onTimeout (/home/ubuntu/code/pss/node_modules/mongoose/node_modules/mongodb-core/lib/topologies/mongos.js:636:28) at ontimeout (timers.js:386:14) at tryOnTimeout (timers.js:250:5) at Timer.listOnTimeout (timers.js:214:5) name: 'MongoError', message: 'no mongos proxy available'
uri: mongodb://10.0.1.49 ,10.0.2.158,10.0.3.84/pss
选项:{ useMongoClient: true, autoReconnect: true, keepAlive: 300000, connectTimeoutMS: 30000 }

对于任何感兴趣的人,这里是useMongoClient参数上的 Mongoose 文档: http ://mongoosejs.com/docs/connections.html#use -mongo-client

“Mongoose 的默认连接逻辑自 4.11.0 起已弃用......此弃用是因为 MongoDB 驱动程序已弃用对 mongoose 的连接逻辑至关重要的 API 以支持 MongoDB 3.6,有关更多详细信息,请参阅此 github 问题。” 这是 GitHub 问题: https ://github.com/Automattic/mongoose/issues/5304

@Blackbaud-SteveBrush 感谢您指出我们的。 所以如果我理解正确

useMongoClient = true => 激活新的连接逻辑,这也适用于 Mongo 3.6
useMongoClient = false => 默认值。 旧连接逻辑 < 4.11.0。 已弃用的那个。

正确的?

@Blackbaud-SteveBrush 关于你的一段代码,就我而言,我不使用

const User = mongoose.connection.model('User', userSchema);

const User = mongoose.model('User', userSchema);

它仍然成功。 谢谢

Mongoose 为我工作 4.10.8 :|

我发现这可能是猫鼬的错误

回滚猫鼬版本后问题消失了

npm卸载-保存猫鼬
npm install -save [email protected]

我完全忽略了这个警告,一切都按预期工作。 也许,这是目前的解决方案。 直接无视(好了。

回滚到 4.10.8 让我的连接再次工作,但我仍然收到错误

Db.prototype.authenticate method will no longe against users in the admin db and will no long connect with auth credentials.

@peterpeterparker正确。 根据我的理解,Mongoose 当前的身份验证代码在 mongodb 3.6 上不起作用,所以useMongoClient代表我们试图在保持向后兼容性的同时解决这个问题。 据我所知,mongodb 3.6 还没有预定的发布日期,所以切换并不紧迫。

@adamreisnz我们有一些错误,但实际上新的连接逻辑是使用本机驱动程序的 MongoClient.connect() 函数的一个非常薄的包装器,这几年来一直是连接到 mongodb 的首选方法。 建立连接后,它会使用相同的 mongodb 驱动程序逻辑来维护连接。 useMongoClient应该只影响初始连接。

@vkarpov15非常感谢您的解释,当然还有工作,非常感谢!

@vkarpov15谢谢,我会试一试并改用useMongoClient看看它会把我们带到哪里。

常量猫鼬 = 要求(“猫鼬”);
const db = " mongodb://localhost/testaroo ";

猫鼬.connection.openUri(db);
mongoose.connection.once("打开", function () {
console.log("连接建立");
}).on("错误", 函数 (错误) {
控制台日志(错误);
})

--我使用这个并且没有发现错误

var mongoose = require('mongoose');
mongoose.Promise = global.Promise;

var mongoDB = mongoose.connect('mongodb://your_database', {
    useMongoClient: true
});

mongoDB
    .then(function (db) {
        console.log('mongodb has been connected');
    })
    .catch(function (err) {
        console.log('error while trying to connect with mongodb');
    });

module.exports = mongoDB;

我用这个,没有发现错误

@vitorbarros它对我有用。 谢谢!

这个对我有用:
http://mongoosejs.com/docs/connections.html#use-mongo-client

我运行了这个快速测试并且它有效:

// index.js
const mongoose = require('mongoose')
mongoose.Promise = global.Promise;
const db = mongoose.createConnection(`mongodb://localhost/test`)

db.on('error', err => console.log(err))
db.once('open', () => {
  console.log(`Connected to Mongo at: ${new Date()}`)
  db.close(() => {
    console.log(`Disconnected from Mongo at: ${new Date()}`)
  })
})

然后node index.js给我:

Connected to Mongo at: Thu Jul 13 2017 22:54:50 GMT+0000 (UTC)
Disconnected from Mongo at: Thu Jul 13 2017 22:54:50 GMT+0000 (UTC)

谢谢你们!

@vitorbarros您的解决方案有效! 谢谢。

我可以确认,用 4.11.3 用@vitorbarros建议的替换连接逻辑可以消除警告并且看起来效果很好👍

无需按照本线程前面的建议重构模型引用。

@vitorbarros的解决方案确实是根据“The useMongoClient Option”文档推荐的方式。

但是,请注意mongoose.Promise = global.Promise;不会_promisify 底层的 Mongo 驱动程序。 根据“MongoDB 驱动程序的承诺”文档promiseLibrary属性也应该在connect方法的选项对象中设置。

例如:

var mongoDB = mongoose.connect('mongodb://your_database', {
    useMongoClient: true,
    promiseLibrary: global.Promise
});

global.Promise将使用本机承诺引擎。 当然,也可以使用 Bluebird 或任何其他引擎,例如promiseLibrary: require('bluebird')

@vitorbarros解决方案对我有用。 我们还需要像@boaz-amit 所说的那样使用 promiseLibrary。
但是哪种方式最适合使用身份验证数据?
在网址中

mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]

或者更好地在选项中设置用户和密码? 我暂时找不到合适的地方。

只是一种验证方式?

这是我的解决方案。 即使第一次连接失败,这也有效。

let firstConnectTimeout = null;
const mongoConnect = () => {
    const mongoDB = mongoose.connect('mongodb://localhost/test', {
        useMongoClient: true
    });

    mongoDB
        .then((db) => {
            clearTimeout(firstConnectTimeout);
        })
        .catch((err) => {
            firstConnectTimeout = setTimeout(mongoConnect, 5000);
        });
};

mongoConnect();

它必须在 url 中,用户/密码选项不再适用
我发现 useMongoClient 是真的。

2017 年 7 月 17 日星期一 20:28 Andrey Prisniak [email protected]
写道:

@vitorbarros https://github.com/vitorbarros解决方案对我有用。 和
我们还需要像 @boaz-amit 一样使用 promiseLibrary
https://github.com/boaz-amit说。
但是哪种方式最适合使用身份验证数据? 在网址中
mongodb://[用户名:密码@
]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[数据库][?options]]
或者更好地在选项中设置用户和密码? 我找不到合适的地方
现在。


你收到这个是因为你被提到了。
直接回复此邮件,在 GitHub 上查看
https://github.com/Automattic/mongoose/issues/5399#issuecomment-315694642
或使线程静音
https://github.com/notifications/unsubscribe-auth/AAd8Qup1YY4lhUhQccv2kLKtraARxvP0ks5sOxs_gaJpZM4OEnIt
.

@adamreisnz @aprisniak正在研究它,请参阅#5419。 同时,请在您的 URI 中输入用户名和密码: mongodb://user:pass<strong i="7">@hostname</strong>:port/db

另外,我写了一篇关于这个选项的博客文章以及为什么它是必要的:http: //thecodebarbarian.com/mongoose-4.11-use-mongo-client.html

@vkarpov15我在 URI 中使用user:pass ,但仍然有警告。

对于那些使用 mongoose 和 gridfs-stream 的人:

const mongooseConnect = mongoose.connect(
    process.env.MONGODB_URI || process.env.MONGOLAB_URI,
    {
        useMongoClient: true
    }
)

let gfs
mongooseConnect.then(conn => {
    gfs = Grid(conn.db)
    /** Setting up GFS storage here */
})

愿你们在打字稿打字时添加缺少的连接选项“useMongoClient”,并将打字添加回这个项目而不是添加打字包。

我不确定我是否应该对这个警告做些什么? 它会被修复的,对吧?

我只是在类型中添加 useMongoClient 以使其工作。 @iamdubx

@FinalDes怎么样? 我添加了mongoose.connect(process.env.DATABASE, { useMongoClient: true })但我仍然收到消息。 我正在使用user:pass in URI

摆脱此类问题的更好方法是使用以下两个命令:
npm卸载-保存猫鼬
npm install -save [email protected]

注意: [email protected]是稳定版。

你们是如何处理创建模式和模型以及访问它们的?

我已经尝试了线程中的所有修复。 有了警告,一切正常。 一旦我尝试useMongoClient: truemongoose.createConnection它就会摆脱警告并且我可以连接到数据库,但是任何尝试访问模型的代码都无法触发。 没有错误,代码永远不会运行。

@iamdubx
只是缺少打字,所以当使用 "noImplicitAny": true 运行时,不会有错误

进口猫鼬=需要(“猫鼬”);
导入 dotenv = 要求(“dotenv”);
dotenv.config();
猫鼬.Promise = global.Promise;
const MONGO_URI=`mongodb://${process.env.MONGODB_HOST}:${process.env.MONGODB_PORT}/${process.env.MONGODB_DB}`;
mongoose.connect(MONGO_URI, {
使用MongoClient:真,
});

@FinalDes你指的是什么? 缺少什么类型? 我有上面相同的代码并且有一个错误。

我在@Snow-Okami 遇到了同样的问题

  1. const mongoDB = mongoose.connect(config.database, { useMongoClient: true });
    这消除了警告并连接到数据库。 但是,尝试访问模型的所有操作都会失败(获取/发布)。 没有错误返回。
  2. const mongoDB = mongoose.connect(config.database, function(){ useMongoClient: true });
    这给出了这两个警告,但除此之外的一切都很好。

请至少提供向后兼容性,我们的生产构建服务器失败。
功能更新很好,但不要更改方法签名或调用。

@Nikunjksanghavi这只是一个警告,不应该失败。

@iamdubx什么样的错误?

@FinalDes弃用错误,我们在这个主题中还讨论什么?

这对我有用:(v.4.11.4)

const MONGO_URI = process.env.MONGO_URI
const mongoose = require('mongoose');

// Use your own promis library
mongoose.Promise = require('bluebird');

// connect to mongo, use Mongo Client
mongoose.connect(MONGO_URI, {useMongoClient: true})
  .then(({db: {databaseName}}) => console.log(`Connected to ${databaseName}`))
  .catch(err => console.error(err));

const poemSchema = mongoose.Schema({
    name: String,
    text: String
});

const Poem = mongoose.model('Poem', poemSchema);

const insertPoem = poem =>
  (new Poem(poem)).save( (err, newPoem) => 
    console.log(err || newPoem));

insertPoem({name: 'poemName', text: 'this is a poem'})

//数据库连接
var 猫鼬 = 要求('猫鼬');
猫鼬.Promise = global.Promise;
mongoose.connect('mongodb://localhost/login_register', {
使用MongoClient:真
})
.then(() => console.log('连接成功'))
.catch((err) => console.error(err));
// DB连接结束

这对我不起作用。 我仍然有控制台警告。 并且没有提供明确的解释。

猫鼬好可怕。 也是我在如此受欢迎的图书馆中看到的最糟糕的文档网站。 多可惜!

现在我正在考虑切换到 RethinkDB。 Linux 基金会——这很严重。
Postgre也很棒。

Mongo - 非常非常耻辱。

@iamdubx你试过我上面的解决方案了吗? 你能把警告贴在上面吗? 也许我可以帮忙:)

@iamdubx可以发布您的警告信息吗?

@FinalDes @shams-ali 我之前发布过,与主题相同的弃用错误。 这个话题是关于的!

(node:3304) DeprecationWarning: `open()` is deprecated in mongoose >= 4.11.0, use `openUri()` instead, or set the `useMongoClient` option if using `connect()` or `createConnection()`. See http://mongoosejs.com/docs/connections.html#use-mongo-client
Server listening on port: 7777
Db.prototype.authenticate method will no longer be available in the next major release 3.x as MongoDB 3.6 will only allow auth against users in the admin db and will no longer allow multiple credentials on a socket. Please authenticate using MongoClient.connect with auth credentials.

@iamdubx很有趣,这与我的警告相同,我发布的上述解决方案似乎为我解决了这个问题。 你能粘贴你更新的无效代码吗?

这对我有用:

// ES6 promises
mongoose.Promise = Promise;

// mongodb connection
mongoose.connect("mongodb://localhost:27017/sandbox", {
  useMongoClient: true,
  promiseLibrary: global.Promise
});

var db = mongoose.connection;

// mongodb error
db.on('error', console.error.bind(console, 'connection error:'));

// mongodb connection open
db.once('open', () => {
  console.log(`Connected to Mongo at: ${new Date()}`)
});

@afoke 很好用,谢谢

@FinalDes不客气,伙计。

这是我的新工作流程,试图遵守警告和弃用:

// db.js
const model = require('./model');
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;


async function db(uri) {
  const con = await mongoose
    .createConnection(uri, {
      useMongoClient: true,
    });

  const {User} = model(con);

  // do something with User
  ...

  // the interface for the server
  return {
    create: params => User.create(params),
    ...
  };
}


module.exports = db;

现在模型模块返回一个连接函数

// model.js
const {Schema} = require('mongoose');


const UserSchema = new Schema({
  name: String,
  age: Number,
});

// Other Schemas
...

module.exports = con => ({
  User: con.model('User', UserSchema),
  ...
});

关于这个主题的任何官方指南?

@iamdubx听起来您不了解warningerror之间的区别。

有问题的警告不会破坏任何东西,但会警告用户将在下一个主要版本中删除的内容。

猫鼬好可怕。

所以请记住,您对开发人员的这种反应会在他们删除功能之前提前警告您。 我还敦促您记住您正在免费使用它,所以在您发脾气之前,请让开发人员从怀疑中受益

@chrisdothtml

有问题的警告不会破坏任何东西,但会警告用户将在下一个主要版本中删除的内容。

它确实污染了测试和控制台,这有点烦人。

猫鼬好可怕。 也是我在如此受欢迎的图书馆中看到的最糟糕的文档网站。 多可惜!

他很不礼貌,这也有点烦人,但他对 Mongoose 文档提出了非常有效的观点。 这不是有史以来最糟糕的文档,但它确实可以改进。

mongoose 转发 mongo 客户端 API 的事实。 它以非常不同的方式工作,使 Mongoose 的用法和文档令人困惑。

一个可能的解决方案是:

  • 停止这样做
  • 删除 Mongo 客户端方法的文档
  • 提供一种在官方客户端和 Mongoose 之间共享连接的方法

我还建议通过将文档分成几页来提高文档的可搜索性,并让新用户更深入地了解 Mongoose 实际为实现某些结果所做的工作。

我有这个错误,但在我添加 {useMongoClient: true} 选项后它消失了。
我使用 Debian 9,测试版,和 MongoDb 版本。 3.2.11 和猫鼬版。 4.10.4。
我有“已连接到 MongoDB”消息(在下面的 Typescript 中查看代码),一切正常。

(<任何>猫鼬).Promise = global.Promise;
mongoose.connect(process.env.MONGODB_URI, {useMongoClient: true});
const db = mongoose.connection;
db.on('error', console.error.bind(console, '连接错误:'));
db.once('open', () => {
console.log('连接到 MongoDB');
设置路线(应用程序);
app.get('/*', function(req, res) {
res.sendFile(path.join(__dirname, '../public/index.html'));
});
app.listen(app.get('port'), () => {
console.log('MyApp 监听端口' + app.get('port'));
});
});

只需卸载您拥有的当前 mongoose 版本并安装较低版本npm install [email protected] --save 。 无需做任何其他事情,这肯定对您有用。

mongoose.connect(database.host, { useMongoClient: true });

这解决了我的问题。 但是在我做出这个改变之后,我又收到了另一个警告。

DeprecationWarning: Mongoose: mpromise (mongoose 的默认承诺库) 已被弃用,请插入您自己的承诺库: http ://mongoosejs.com/docs/promises.html

此代码解决了所有弃用警告:
```javascript
猫鼬.Promise = global.Promise;
猫鼬.connect(uri,{
保活:真,
reconnectTries: Number.MAX_VALUE,
使用MongoClient:真
});
````
通过链接了解更多信息 -> http://mongoosejs.com/docs/connections.html#use -mongo-client

@bricss太棒了! 谢谢!

@bricss你让我开心。

有人获得了英雄徽章...

编辑: @bricss它为我消除了弃用警告,但我无法从我的 mLab 沙箱中检索数据。 这可能是因为他们使用的是旧版本的 MongoDB。 我稍后会尝试检查它。

编辑: @bricss现在可以与最新的 mongoose 4.11.9 和 Azure 上的 Cosmos DB 连接正常工作。

@bricss :砖块做得很好! 即使我在本地使用的是非常旧版本的 mongodb,它也对我有用:+1:

@bricss太棒了! 但是您可以考虑为“reconnectTries”设置一个较小的数字。 如果您的数据库出现问题,您不想花一整天的时间重新连接。

@afoke的解决方案对我有用,只有当我在连接字符串中明确声明数据库时,即mongodb://localhost:27017/test但不是mongodb://localhost:27017

我可以在没有此警告的情况下创建与 2 个 DB 的连接吗? 我需要将我的模型与不同的数据库一起使用。

使用 mongoose v^4.11.6 ,当添加useMongoClient时,警告消失了。

const uri = "http://blablabla.blo/blaDB"; mongoose.Promise = global.Promise; mongoose.connection.on('error', (err) => { console.error( Mongoose 连接错误:${err}`);
process.exit(1);
});
mongoose.connect(uri, {useMongoClient: true});

 // load models
 require('./model1');
 // ...
 require('./modelN');`

以这种方式连接到数据库可以解决问题:
mongoose.connect(url,{user:'username',pass:'mypassword',useMongoClient:true});

这些错误是否会导致问题,例如安全问题?

如果我使用这种语法,就不会再弹出“已弃用”警告🎉

mongoose.connection.openUri('mongodb://localhost/test')
  .once('open', () => console.log('Good to go !'))
  .on('error', (error) => {
    console.warn('Warning', error);
  });

我面临以下相同的弃用警告:
(node:2300) DeprecationWarning: open()在 mongoose >= 4.11.0 中已弃用,请改用openUri() ,或者如果使用connect()则设置useMongoClient选项或createConnection() 。 请参阅http://mongoosejs.com/docs/connections.html#use -mongo-client

解决方案

我尝试了以下,它工作正常。 不给出弃用警告。

mongoose.connect('mongodb://127.0.0.1:27017/your-database-name', { useMongoClient: true, promiseLibrary: global.Promise });

希望这将帮助每个面临这个问题的人。

我有同样的问题,但是当尝试连接到 Mongo Atlas 服务时,它只是没有使用 {useMo ngoClient:true } 选项连接,没有它,连接将不再执行。

有同样问题的人吗?

我通过将 mongoose.connect 更改为 mongoose.createConnection 解决了我的问题

mongoose.createConnection(config.uri, (err) => {
如果(错误){
console.log('无法连接数据库:', err);
} 别的 {
console.log('连接到数据库:' + config.db);
}
});

我这样解决了这个问题(Mongoose 4.12.0,NodeJS - 7.10.1)

mongoose.Promise = require('bluebird');
mongoose.connect('mongodb://localhost:27017/books_exchange', {
  useMongoClient: true,
  promiseLibrary: require('bluebird')
}).then(() => {
  var userSchema = new mongoose.Schema({
    name: String,
    password: String
  });
  var User = mongoose.model('User', userSchema);

  var person = new User({
    name: "John",
    password: "qwerty"
  });

  person.save().then(() => {
    console.log('Data saved');
  }).catch(e => {
    console.log(e);
  });
}).catch(e => {
  console.log('Error while DB connecting');
  console.log(e);
});
此页面是否有帮助?
0 / 5 - 0 等级