Mongoose: 弃用警告

创建于 2016-07-01  ·  79评论  ·  资料来源: Automattic/mongoose

我收到此警告

(node:3341) DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html

在我做之后

driver.createCar({
          carName: 'jeep',
          availableSeats: 4,
        }, callback);

driver 是 Driver 类的一个实例

const carSchema = new Schema({
  carName: String,
  availableSeats: Number,
  createdOn: { type: Date, default: Date.now },
});
const driverSchema = new Schema({
  email: String,
  name: String,
  city: String,
  phoneNumber: String,
  cars: [carSchema],
  userId: {
    type: Schema.Types.ObjectId,
    required: true,
  },
  createdOn: { type: Date, default: Date.now },
});
const DriverModel = mongoose.model('Driver', driverSchema);

class Driver extends DriverModel {
  getCurrentDate() {
    return moment().format();
  }
  create(cb) {
    // save driver
    this.createdOn = this.getCurrentDate();
    this.save(cb);
  }
  remove(cb) {
    super.remove({
      _id: this._id,
    }, cb);
  }
  createCar(carData, cb) {
    this.cars.push(carData);
    this.save(cb);
  }
  getCars() {
    return this.cars;
  }
}

关于我做错了什么有什么想法吗?

最有用的评论

我解决了那个警告

mongoose.Promise = global.Promise;

在调用 mongoose.connect 之前

// connect to mongo function
core.connect = function connect(opts) {
  mongoose.Promise = global.Promise;
  mongoose.connect(`mongodb://${opts.server}:${opts.port}/${opts.db}`);
  return mongoose.connection;
};

所有79条评论

嗯,你在任何地方都使用承诺吗? 除非您使用承诺,否则您不应该收到此警告...

不,我没有使用承诺

我也刚开始遇到这个问题。 不使用我知道的承诺!

我解决了那个警告

mongoose.Promise = global.Promise;

在调用 mongoose.connect 之前

// connect to mongo function
core.connect = function connect(opts) {
  mongoose.Promise = global.Promise;
  mongoose.connect(`mongodb://${opts.server}:${opts.port}/${opts.db}`);
  return mongoose.connection;
};

是的,如果您使用 Promise,这个警告应该告诉您更改 mongooses 默认 Promise 库,但除非您在某处调用 .then,否则它不应该发生

我明白了,但我只是在保存对象的地方得到它,然后在回调中修改它并再次保存

我已经尝试过@SAudelOG方法在 mongoose 连接之前向 mongoose 分配一个承诺,但我仍然收到此错误

我正在使用异步函数 es7,当我尝试 Model.findOne({}) 时我的代码被阻止

@SAudelOG提供的解决方案有效。 像@IrishAdo我也只有在保存对象时才会得到这个。 也许是因为我正在使用 Bluebird Promise 库的猫鼬插件之一。

这是我正在使用的依赖项列表

  "dependencies": {
    "async": "^2.0.0-rc.6",
    "body-parser": "^1.15.0",
    "bower": "^1.7.7",
    "compression": "^1.6.1",
    "connect-mongo": "^1.2.1",
    "consolidate": "^0.14.1",
    "cookie-parser": "^1.4.3",
    "express": "^4.13.4",
    "express-jwt": "^3.4.0",
    "express-session": "^1.13.0",
    "express-validator": "^2.20.8",
    "faker": "^3.1.0",
    "http-errors": "^1.5.0",
    "jsonwebtoken": "^7.0.1",
    "lodash": "^4.13.1",
    "method-override": "^2.3.5",
    "mongoose": "^4.4.3",
    "mongoose-beautiful-unique-validation": "^3.0.0",
    "mongoose-delete": "^0.3.3",
    "mongoose-validator": "^1.2.5",
    "morgan": "^1.6.1",
    "passport": "^0.3.2",
    "passport-local": "^1.0.0",
    "swig": "^1.4.2"
  }

我没有使用插件,也没有使用 Promise,也没有收到此警告(在 [email protected] 上)。

使用“--trace-deprecation”运行我的应用程序,我得到了:

Trace: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead:
http://mongoosejs.com/docs/promises.html
    at Object.exports._printDeprecationMessage (internal/util.js:30:13)
    at Promise.deprecated [as then] (internal/util.js:54:22)
    at fnWrapper (.\node_modules\mongoose\node_modules\hooks-fixed\hooks.js:188:11)
    at EmbeddedDocument.Object.defineProperty.value.fn (.\node_modules\mongoose\lib\schema.js:219:11)
    at _next (.\node_modules\mongoose\node_modules\hooks-fixed\hooks.js:62:30)
    at fnWrapper (.\node_modules\mongoose\node_modules\hooks-fixed\hooks.js:186:18)
    at EmbeddedDocument.Object.defineProperty.value.fn (.\node_modules\mongoose\lib\schema.js:173:18)
    at EmbeddedDocument._next (.\node_modules\mongoose\node_modules\hooks-fixed\hooks.js:62:30)
    at EmbeddedDocument.proto.(anonymous function) [as $__original_save] (.\node_modules\mongoose\node_modules\hooks-fixed\hooks.js:108:20)
    at .\node_modules\mongoose\lib\document.js:1917:24
    at new Promise.ES6 (.\node_modules\mongoose\lib\promise.js:45:3)
    at EmbeddedDocument.wrappedPointCut [as save] (.\node_modules\mongoose\lib\document.js:1893:14)
    at async.each.i (.\node_modules\mongoose\lib\schema.js:225:18)
    at .\node_modules\async\lib\async.js:181:20
    at Object.async.forEachOf.async.eachOf (.\node_modules\async\lib\async.js:233:13)
    at Object.async.forEach.async.each (.\node_modules\async\lib\async.js:209:22)
    at model.Object.defineProperty.value.fn (.\node_modules\mongoose\lib\schema.js:223:15)
    at _next (.\node_modules\mongoose\node_modules\hooks-fixed\hooks.js:62:30)
    at fnWrapper (.\node_modules\mongoose\node_modules\hooks-fixed\hooks.js:186:18)
    at .\node_modules\mongoose\lib\schema.js:200:17
    at .\node_modules\mongoose\node_modules\kareem\index.js:127:16
    at nextTickCallbackWith0Args (node.js:420:9)
    at process._tickDomainCallback (node.js:390:13)

我有同样的问题,如果它有任何帮助,当我尝试创建其中包含子文档数组的文档时,它会特别触发,例如:

var data = {
  field: 'value',
  another_field: [{subdocfield1: 'value', subdocfield2: 'value'}]
} 

mySchema.create(data, cb)

其他没有子文档的集合不会发生这种情况,如果我发出没有子文档数据的 create 语句,它甚至不会发生,如下所示:

var data = {
  field: 'value'
} 

mySchema.create(data, cb)

_Note:_ mongoose.Promise = global.Promise确实为我解决了警告问题

当我在文档上使用remove()时遇到相同的折旧警告。 我没有在这里或我的代码中的任何其他地方使用承诺。

我在使用Model.create(objects, callback);时遇到了这个错误,也许这个修复还没有发布到 npm?

得到这个,很高兴阅读它并不令人震惊。 当它发生时,我会仔细研究它以帮助调试。

也得到这个,而且我没有在任何地方使用猫鼬承诺。

我能够将其追溯到库on-headers回调中的model.save调用,并且模型是在回调之外创建的,在它被调用之前,以防它帮助任何人。 将模型创建和保存调用都放在回调中没有区别。

在节点 v4.4.6 上面临这个问题,而在 v4.4.2 上这似乎有效

@SKatiyar代码示例

和我一样,在调用 save() 方法后收到此消息,足以让我关心

这行得通! 在mongoose.connect(MONGO_URI);之前添加mongoose.Promise = global.Promise;

以下代码足以在我身上重现:

const mongoose = require('mongoose');
const schema = new mongoose.Schema({
  data: { type: Number }
});
const Model = mongoose.model('schema', schema);
mongoose.connect('mongodb://127.0.0.1:27017/somedatabase');
const newModel = new Model({ data: 1 });
const save = newModel.save(() => {
  console.log('saved model');
});
console.log(typeof save.then); //=> 'function'

我在这里看到的奇怪的事情是,使用newModel.save(callback)仍然返回一个承诺(或者我假设这是一个承诺,因为.then的类型是'function' )。 这是预期的行为吗?

这是我的版本:
节点: v6.3.1
猫鼬: v4.5.8

如果您需要我提供任何其他信息,请告诉我。

@dvlsg是的,这是当前的预期行为,即使您通过回调, save 也将始终返回一个承诺

好吧,我想这至少可以解释为什么即使人们认为他们没有使用 Promise 也会看到 Promise 警告。

这解释了一切..我只是有点偏执,想摆脱所有警告💃

这是我的错,是的 .save() 返回一个承诺,所以这是意料之中的,但是,警告让我感到奇怪。 http://mongoosejs.com/docs/promises.html (只需阅读第一段🎱)

所以.save()返回一个承诺,但除非你调用.then() ,否则你不应该收到这个警告。 如果您没有在代码中调用.then()就收到此警告,这意味着 mongoose 在不应该使用的地方使用了 Promise,因此请使用代码示例打开一个单独的问题:+1:

恕我直言,这个消息应该是一个错误(“事情不工作”)而不是一个警告(“注意,但它应该工作”),因为它实际上在回调中作为错误返回。

我遇到了这个问题,aModel.save() 方法无法放入 MongoDB。 这个问题的根本原因需要一些时间。 应用“mongoose.Promise = global.Promise;”后,就成功了。

我使用的是“猫鼬”:“^4.5.9”。

Save 应该可以使用默认的 Promise 库正常工作,您可以提供代码示例吗?

@vkarpov15

你说得对。 我刚刚尝试并未能从头开始重新创建带有警告的阻止保存结果。

我不确定它是否与我项目中的其他代码有关。 需要一些时间来检查。 在我找出原因之前请忽略。

对我来说,每当我使用 .then() 时,此日志都会在控制台中弹出,它是否与 mongoose 对象或与 mongoose 无关的任何其他对象一起使用都没有关系

所以,根据文档,我正在传递

'use strict';
var Promise = require('bluebird');

// Development specific configuration
// ==================================
module.exports = {
  // MongoDB connection options
  mongo: {
    uri: 'mongodb://localhost/fullstack-dev',
    options: {
      promiseLibrary: Promise
    }
  },
  // .. other config
};

然后在我的主文件中做

'use strict';

// Set default node environment to development
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
process.env.BLUEBIRD_DEBUG = 1;
var mongoose = require('mongoose');
var config = require(path.join(__dirname, 'server', 'config', 'environment'));

// Connect to database
var db = mongoose.connect(config.mongo.uri, config.mongo.options);
mongoose.connection.on('error', function(err) {
  console.error('MongoDB connection error: ' + err);
  process.exit(-1);
});

而且我在做query.exec时仍然收到弃用警告。 关于我做错了什么有什么建议吗?
[编辑:添加猫鼬和蓝鸟版本]
我正在使用猫鼬^4.6.1 ,蓝鸟^3.4.6

我在猫鼬 4.6.1 和节点 4.4.5 上也收到警告

    var mongoose = require('mongoose');
    mongoose.Promise = global.Promise;
    mongoose.connect(dbConfig);
    var connection = mongoose.connection;

@manu29d看起来你没有设置mongoose.Promise = bluebird

@vkarpov15我想我是。 我在配置脚本的开头声明var Promise = ,然后在后面声明了promiseLibrary: Promise 。 (查看示例中的第一个代码片段)

另外,我尝试按照文档中给出的方式编写promiseLibrary: require('bluebird')

我在您提供的代码示例中的任何地方都没有看到mongoose.Promise = require('bluebird')var Promise = require('bluebird'); _不_正确。

@vkarpov15我指的是http://mongoosejs.com/docs/promises.html#promises -for-the-mongodb-driver

这仍然有效吗? 我没有时间检查配置中是否仍然支持此选项( promiseLibrary )或已被删除的代码。

设置mongoose.Promise = global.Promise是可行的。

mongoose.Promise = global.Promise
mongoose.connect之前也适用于我。

在连接工作之前,我没有使用承诺并调用mongoose.Promise = global.Promise

@manu29d这些文档是正确的,但是,如果您实际阅读它们,您会发现promiseLibrary选项仅影响底层 mongodb 驱动程序,_not_ mongoose 模型。

@zubair-farooqui-10p 以下脚本在 4.5.9 或 4.6.3 中不会为我触发警告:

'use strict';

Error.stackTraceLimit = Infinity;

var assert = require('assert');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/gh4291');
mongoose.set('debug', true);

var connection = mongoose.connection;

你必须添加这个额外的行真的很烦人,有没有办法让猫鼬在他们的内部库中修复它? 谢谢!

不是一般情况,因为 mongoose 的 promise lib 切换机制的工作方式与 mongodb 驱动程序的工作方式完全不同。 在 mongoose 中,它只是一个您可以随时在 mongoose 全局对象上设置的属性,而在 mongodb 驱动程序中,它是一个连接选项,因此不同的连接可以有不同的承诺库,但您只能在连接时设置承诺库,不是之后。 调和这些差异并不是真正的优先事项。

为什么在保存包含字符串数组的文档时会发生这种情况,谁能详细说明

我在调用.createConnecton()后也得到了它。 我用Q做的有趣的事情......但是! 但我更喜欢在建立连接之后执行此操作,因为我(而且我很确定每个人)更喜欢在 var 声明块中执行此操作。 IE

var mongoose = require('mongoose'),
        connection1 = mongoose.createConnection(dbConn1Str),
        connection2 = mongoose.createConnection(dbConn2Str)
;
mongoose.Promise = Q.makePromise;

相反,为了摆脱这个警告,我不得不这样做:

var mongoose = require('mongoose'),
        connection1, connection2
;
mongoose.Promise = Q.makePromise;
connection1 = mongoose.createConnection(dbConn1Str)
connection2 = mongoose.createConnection(dbConn2Str)

没什么大不了的,但是很srsly...

是的,这就是要走的路。 Mongoose 4.x 将使用 mpromise,直到您告诉它不要这样做。

我在使用带有查询助手的常规 find() 调用时看到了这一点。 我不在任何地方使用then

BookStore.find().byUsingQueryHelper(1,2,3).lean().exec(function (err, docs) { ... })

日志:

猫鼬:书店.find({位置:{'$near':[28.742712943610545,-13.865369983731426],'$maxDistance':0.0012556898446083817}},{限制:10,字段:未定义})

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

@pronebird不幸的是,这就是exec()在内部工作的方式,对exec()的回调实际上是通过一个承诺。 只需执行mongoose.Promise = global.Promise就不会再收到该警告了。

@pronebird我在发布时遇到了同样的错误,我发现我的架构具有如下所示的默认值,并且与我在下面发布的值不匹配
角色: {
类型:字符串,
枚举:['客户','管理员'],
默认值:“客户端”
}
我发布角色:管理员,它应该是管理员
希望这个答案对某人有所帮助。 谢谢

@Muhammedalbayati我认为您的问题与这个特定问题无关? 这只是 Mongoose 发出的关于承诺的警告。

@varunjayaraman你是对的,我应该提到以下内容
警告
DeprecationWarning: Mongoose: mpromise (mongoose 的默认承诺库) 已被弃用,请插入您自己的承诺库: http ://mongoosejs.com/docs/promises.html

通过添加mongoose.Promise = global.Promise; 在连接到数据库之前
mongoose.connect('mongodb://localhost:27017/mydb');

@Muhammedalbayati我认为@vkarpov15解释了为什么会出现这个警告。 Mongoose 在exec内部使用了 Promise。

在我将 mongoose 升级到 v.4.7.7 后,ES6“yiled”就不能与 doc.save 方法一起使用。
最后只是因为mongoose.Promise = global.Promise 。 在我删除它之后它仍然警告

Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead:

我猜[email protected]有它自己的 promise 模块。 是对的吗??
有人知道吗?

它是猫鼬添加一个 es6-promise 库。

这么愚蠢的问题!

PS:把那个他妈的警告推到你的阴户上!

作为一个讲俄语的同伴,我为这个小人物的行为表示歉意,敦促你不要翻译它在这里写的东西。

@vkarpov15我已经尝试过mongoose.Promise = global.Promise;mongoose.Promise = require('bluebird');

不幸的是,我仍然收到弃用警告。

_是不是我做错了什么?_

const mongoose = require('mongoose');

mongoose.Promise = global.Promise;

mongoose.connect('mongodb://localhost/users_test');

mongoose.connection
  .once('open', () => {
    console.log('connectecd to db')
  })
  .on('error', (err) => {
    console.warn('Warning', err)
  });

@protoEvangelium您是否在应用程序的其他地方导入猫鼬? 这是第一次使用 mongoose 还是将这个文件导入另一个文件?

另外你使用的是什么版本的猫鼬/节点?

@varunjayaraman此文件未在其他任何地方导入。 但是,我在我的 user.js 模式文件中导入猫鼬,然后在我的一些测试中使用该用户模式。

const mongoose = require('mongoose')
const Schema = mongoose.Schema
const UserSchema = new Schema({
  name: String,
})
const User = mongoose.model('user', UserSchema)
module.exports = User

节点 v7.0.0猫鼬 v4.8.1

@protoEvangelium您是在应用程序中还是仅在测试中收到警告?

我曾经遇到过同样的问题 - 罪魁祸首是另一个模块,它使用了它自己的 mongoose 依赖项。 此类模块的 package.json 中有类似"mongoose": "^4.1.1"的内容,但由于这些模块每年更新一次(如果有的话) - 它们缺少承诺配置部分。 @protoEvangelium你在使用其他模块吗?

@SAudelOG感谢您的回答

@varunjayaraman我才开始测试使用 Mongoose 和 Mocha 将用户添加到 Mongo。 到目前为止,这是一个准系统项目。

@Spown我正在使用:
"mocha": "^3.2.0", "mongoose": "^4.8.1", "nodemon": "^1.11.0"

谢谢 :)

@protoEvangelium等一下,你试过了吗?

const mongoose = require('mongoose')
mongoose.Promise = global.Promise // <--
const Schema = mongoose.Schema
const UserSchema = new Schema({
  name: String,
})
const User = mongoose.model('user', UserSchema)
module.exports = User

如果您从未重新定义承诺的猫鼬实例创建模型 - 此模型的每个查询都会引发警告。

@Spown

我在正确的时间遇到​​了这个线程。 每当我保存信息时,我都会收到相同的警告。 原来我是从 mongoose 的一个实例创建一个模型,并没有重新定义它。 要求 bluebird 并将其设置为 mongoose.Promise 解决了错误消息。

非常感谢!

@Spown谢谢先生! 这就是问题所在。 有趣的是,在连接到 Mongoose 之前,我在test_helper.js文件中定义mongoose.Promise = global.Promise; 。 我将mongoose.Promise = global.Promise;切换到我定义架构的文件中,它可以工作!!! 不再有弃用警告👍

const mongoose = require('mongoose')
mongoose.Promise = global.Promise;
const Schema = mongoose.Schema

在我的模式中使用“可填充”虚拟时,我遇到了这个问题。 使用--trace-deprecations运行我的应用程序,您可以看到罪魁祸首:

(node:8846) DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html
    at model.wrappedPointCut [as init] (/Users/fleavamini/Projects/stellium/stellium-express/node_modules/mongoose/lib/services/model/applyHooks.js:141:26)
    at completeMany (/Users/fleavamini/Projects/stellium/stellium-express/node_modules/mongoose/lib/query.js:1254:12)
    at Immediate.cb (/Users/fleavamini/Projects/stellium/stellium-express/node_modules/mongoose/lib/query.js:1117:13)
    at Immediate.<anonymous> (/Users/fleavamini/Projects/stellium/stellium-express/node_modules/mquery/lib/utils.js:137:16)
    at runCallback (timers.js:651:20)
    at tryOnImmediate (timers.js:624:5)
    at processImmediate [as _immediateCallback] (timers.js:596:5)

我已经做出了承诺(注意我使用的是 TypeScript):

import * as mongoose from "mongoose";
(<any>mongoose).Promise = global.Promise;
mongoose.connect('mongodb://localhost/blah')

有任何想法吗? 我应该在每个使用“可填充”虚拟的模型上设置承诺吗? 等一下,我实际上会尝试一下,然后回来看看它是怎么回事。

好的,经过一番修改,我发现我仍然需要在我的架构上设置Promise ,即使我已经在我的服务器的index中设置了它。

就我而言, website_pages集合是我的系统查询的第一个集合,仅在此模式上将mongoose.Promise设置为global.Promise就解决了问题,我不需要在所有模式中设置它。

为什么不使用 ES6 Promises? 现在不是到处都有了吗?

mongoose.Promise = Promise; // eh?

谢谢@Spown ,因为我在导入模型后放置mongoose.Promise = global.Promise ,所以我遇到了同样的弃用警告。 现在弃用警告消失了。

@Spown所述,在模型文件中声明mongoose.Promise = global.Promise有效。 这是由于节点对所需模块的缓存。 不过,这似乎变化无常。 有没有办法确保首先加载test_helpers.js以便我可以在这个文件中设置 mongoose 的 promise 函数?

有没有办法确保...

就个人而言,我在我的项目中只require mongoose 一次,然后我将它放入一个全局 Singleton 对象中,并在所有数据库中使用它。 不完全优雅,但主要是防弹的。 而且我在弃用之前很久就已经这样做了,因为如果您使用自定义连接,我会这样做(通过mongoose.createConnection()而不是mongoose.connect()建立的连接) - 您必须创建模型来自链接到此连接的 mongoose 实例。 否则它根本不起作用,这比一些讨厌的警告要糟糕得多。

是的,我和@Spown 一样。 这当然不理想,但它是保持 mongoose 向后兼容的唯一方法,直到我们可以完全弃用 mpromise 的下一个主要版本

库/猫鼬.js

import mongoose from 'mongoose'; // real mongoose only be required once here 

mongoose.Promise = global.Promise; // so that you dont have to do this on every require
const Schema = mongoose.Schema;

export {
  mongoose as default, // kind of singleton
  mongoose,
  Schema,
};

index.js

import mongoose from './libs/mongoose';
mongoose.connect(process.env.MONGODB_URI);

模型/user.js

import {mongoose, Schema} from '../libs/mongoose';

export default mongoose.model('User', new Schema({
  name: String,
  password: String,
}));

@howard require() 调用被缓存。

因此,如果我理解正确,我需要在每个模式声明之前设置承诺,而不是只在一个地方进行(例如在我的索引文件或我设置连接的地方)
这不是一个好习惯,值得考虑将其更改为函数,例如:
mongoose.setPromise(global.Promise);

@sh-guti 我想是的,我遇到了同样的问题,那段代码解决了这个问题。

在这一点上,我不知道是否使用回调或承诺。 哈哈。

利用

mongoose.createConnection(URI)

谁能解释一下,为什么地球上的猫鼬会否认原生 Promise 的存在并且不能开箱即用?

向后兼容性。 在节点 4 发布之前,Mongoose 4.x 已经存在了一年多。 我们将切换到下一个向后突破的版本。

这会是什么时候?

mongoose.createConnection(URI) 会导致 Mongoose 出现一个非常奇怪的错误,调试数小时后查询不起作用。 最终回到

mongoose.connect(process.env.MONGODB); 来自 mongoose.createConnection(process.env.MONGODB)

作为旁注,它确实停止了贬值警告..但停止了一切工作......

@MickL我们将在接下来的几周内发布 rc0,在 twitter 上关注 mongoose 或加入 slack 频道以获取更新

此页面是否有帮助?
0 / 5 - 0 等级