(nó: 3341) Aviso de suspensão de uso: Mongoose: mpromise

89

Estou tentando desenvolver uma classe no topo do mangusto com meus métodos personalizados, então estendi o mangusto com minha própria classe, mas quando invoco para criar um novo método de carro, ele funciona, mas é despojado e com erro, aqui deixo você veja o que estou tentando fazer.

Estou recebendo este aviso

(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

depois que eu faço

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

driver é uma instância da classe 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;
 }
}

alguma ideia sobre o que estou fazendo de errado?

Audel O. Gutierrez
fonte
3
O escritor de Mongoose diz que: "Basta fazer mongoose.Promise = global.Promisee você não receberá mais esse aviso." github.com/Automattic/mongoose/issues/…
efkan

Respostas:

240

Aqui está o que funcionou para eu esclarecer o problema, depois de ler os documentos: http://mongoosejs.com/docs/promises.html

O exemplo no doc está usando a biblioteca de promessa bluebird, mas eu escolhi ir com promessas ES6 nativas.

No arquivo para o qual estou ligando mongoose.connect:

mongoose.Promise = global.Promise;
mongoose.connect('mongodb://10.7.0.3:27107/data/db');

[EDITAR: Obrigado a @SylonZero por trazer à tona uma falha de desempenho em minha resposta. Visto que essa resposta é tão bem vista, sinto o dever de fazer esta edição e encorajar o uso de bluebirdpromessas nativas. Leia a resposta abaixo para obter detalhes mais informados e experientes. ]

Hunter Lester
fonte
3
Depois de verificar o benchmark no site: bluebirdjs.com/docs/benchmarks.html @SylonZero está se referindo, acredito que a solução dele vale a pena votar em vez da primeira proposta. Ainda agradeço a Hunter Lester por este excelente trabalho e investigação e por compartilhar suas descobertas!
Isak La Fleur
Obrigado por sua edição, que me fez perceber uma grande falha de desempenho
Yusuf Kamil AK
71

Embora a resposta acima seja precisa e funcione, você deve considerar o problema de desempenho se tiver um aplicativo Node real de produção.

A solução acima usará promessas ES6 nativas - que são 4X mais lentas que o bluebird nos benchmarks que compartilhei abaixo. Isso pode afetar drasticamente o desempenho de uma API escrita em Node e usando MongoDB.

Eu recomendo usar o Bluebird:

// Assuming you store the library in a var called mongoose
var mongoose = require('mongoose');

// Just add bluebird to your package.json, and then the following line should work
mongoose.Promise = require('bluebird');

Resultados de referência

Plataforma: (usando o Node mais recente no momento da escrita)

  • Linux 4.4.0-59-x64 genérico
  • Node.JS 6.9.4
  • V8 5.1.281.89
  • CPU Intel (R) Core (TM) i7-6500U a 2,50 GHz × 4
  • 16 GB de RAM com 500 GB SSD

    | file                                      | time(ms) | memory(MB) |
    |-------------------------------------------|----------|------------|
    | callbacks-baseline.js                     | 114      | 25.09      |
    | callbacks-suguru03-neo-async-waterfall.js | 152      | 32.98      |
    | promises-bluebird-generator.js            | 208      | 29.89      |
    | promises-bluebird.js                      | 223      | 45.47      |
    | promises-cujojs-when.js                   | 320      | 58.11      |
    | promises-then-promise.js                  | 327      | 64.51      |
    | promises-tildeio-rsvp.js                  | 387      | 85.17      |
    | promises-lvivski-davy.js                  | 396      | 81.18      |
    | callbacks-caolan-async-waterfall.js       | 527      | 97.45      |
    | promises-dfilatov-vow.js                  | 593      | 148.30     |
    | promises-calvinmetcalf-lie.js             | 666      | 122.78     |
    | generators-tj-co.js                       | 885      | 121.71     |
    | promises-obvious-kew.js                   | 920      | 216.08     |
    | promises-ecmascript6-native.js            | 931      | 184.90     |
    | promises-medikoo-deferred.js              | 1412     | 158.38     |
    | streamline-generators.js                  | 1695     | 175.84     |
    | observables-Reactive-Extensions-RxJS.js   | 1739     | 218.96     |
    | streamline-callbacks.js                   | 2668     | 248.61     |
    | promises-kriskowal-q.js                   | 9889     | 410.96     |
    | observables-baconjs-bacon.js.js           | 21636    | 799.09     |
    | observables-pozadi-kefir.js               | 51601    | 151.29     |
    | observables-caolan-highland.js            | 134113   | 387.07     |
SylonZero
fonte
1
para meu entendimento: de onde vem o seu benchmark? Existe um consenso em torno desses resultados? Parece que todos estão votando pela resposta padrão da promessa do ES6, mas gostaria de me aprofundar nos problemas de desempenho que você mencionou.
Zedenem 01 de
1
O benchmark é de um conjunto de testes que você pode ler (e verificar) no repositório bluebird git - executei-os novamente localmente para obter os resultados acima porque precisava dos resultados de 2017 para compartilhar com outros. Mais importante, experimentei ganhos de desempenho em nossa própria API (tenho 5 microsserviços e uma meta de escalabilidade difícil) e sempre tive que tomar decisões para usar retornos de chamada aninhados simples em vez de promessas (ainda o mais rápido). Pessoalmente, acho que os benchmarks são apenas o primeiro passo para uma decisão, mas não posso compartilhar meus dados internos ainda ... minha meta de escala é de 10 mil usuários por máquina física.
SylonZero 01 de
Além disso, o voto favorável dificilmente é uma medida completa sobre uma resposta. Em minha experiência, muitos raramente vão fundo depois que um problema foi resolvido (ou lêem qualquer outra coisa) e muitos programadores que eu orientei no passado precisavam ser ensinados sobre habilidades de desempenho e instrumentação para código.
SylonZero 01 de
Muito obrigado por trazer à tona os problemas de desempenho. Sou um programador novato, apenas 2 anos nisso, e anseio por essa educação. Estou usando isso na produção, então fico ainda mais feliz em saber se é. Quais são as melhores maneiras de fazer benchmarking de programas e partes de código?
Hunter Lester
1
Hunter, isso dependeria da natureza da plataforma e do código, mas relacionado a esta questão: existem dois lados para obter insights - 1. bons testes para usar por meio de um gerador de carga para simular solicitações do usuário. Eu uso o Apache jMeter para testar minha API do Node e para gerar carga para vários usuários. 2. Instrumentação: como você rastreia as transações individuais. Eu uso NewRelic para instrumentar meu código de Node - ele fornece uma análise detalhada de cada transação em ms (até a rota Express, tempo de consulta Mongo, Redis para sessões, etc.). Espero que isso ajude você a começar.
SylonZero
2

você tentou isso? Por exemplo :

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

se você criar um modelo a partir de uma instância do mangusto cuja promessa não foi redefinida - todas as consultas nesse modelo gerariam um aviso.

Krishan Kant Sharma
fonte
2

Acho que você tem sua resposta, mas eu uso global.promise com tratamento de erros

// MongoDB connection
mongoose.Promise = global.Promise;

var promise = mongoose.connect('mongodb://localhost:27017/test_db', {
  useMongoClient: true,
});

promise.then(function(db) {
    console.log("Connected to database!!!");
}, function(err){
    console.log("Error in connecting database " + err);
});
Saurabh Lende
fonte
1
var mydb;
var uri = 'mongodb://localhost/user1';
var promise = mongooose.connect(uri,{
      useMongoClient: true,
});
promise.openUri(uri,function(errr,db){
if(errr){
        throw errr;
      }else{
        console.log("Connection Successfull");      
        mydb = db;
      }
});

É preciso ter conexão com a ajuda da promessa na última versão do mangusto [este é o link] [1] [1]: http://mongoosejs.com/docs/promises.html

Yashwin Munsadwala
fonte
0

Basta adicionar o segundo parâmetro como um objeto ao método connect ().

mongoose.connect('dbUrl', {
  useMongoClient: true
});

Consulte: http://mongoosejs.com/docs/connections.html#use-mongo-client

Aaman
fonte
Só isso não remove o aviso. Também precisamos mapear a promessa global, conforme mencionado acima.
Balasubramani M,
0

Mongoose 4.8.6

Se você encontrar um erro como este:

(nó: 9600) Aviso de descontinuação: Mongoose: mpromise (biblioteca de promessa padrão do mongoose) está obsoleta, conecte sua própria biblioteca de promessa: http://mongoosejs.com/docs/promises.html

Você também precisa definir opções que prometem a biblioteca a ser usada para o driver.

mongoose.Promise = global.Promise
mongoose.connect(uri, { useMongoClient: true, options: { promiseLibrary: mongoose.Promise }})
dimpiax
fonte
0
var mongoose = require('mongoose');
mongoose.Promise = global.Promise;
db = mongoose.connect(env.DATABASE_URI, function(){
  //
})

este trabalho para mim.

Sigit Kuncoro
fonte