(węzeł: 3341) Wycofanie Ostrzeżenie: Mongoose: mpromise

89

Próbuję rozwinąć klasę na szczycie mangusty za pomocą moich niestandardowych metod, więc rozszerzyłem mangustę o własną klasę, ale kiedy wywołuję utworzenie nowej metody samochodu, działa, ale jej pasek i błąd, tutaj pozwolę ci zobacz, co próbuję zrobić.

Otrzymuję to ostrzeżenie

(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

po tym, jak to zrobię

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

driver jest instancją klasy 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;
 }
}

jakieś myśli o tym, co robię źle?

Audel O. Gutierrez
źródło
3
Pisarz Mongoose mówi: „Po prostu zrób, mongoose.Promise = global.Promisea nie powinieneś już otrzymywać tego ostrzeżenia”. github.com/Automattic/mongoose/issues/…
efkan

Odpowiedzi:

240

Oto, co pomogło mi rozwiązać problem po przeczytaniu dokumentów: http://mongoosejs.com/docs/promises.html

Przykładem w dokumencie jest użycie biblioteki obietnic bluebird, ale zdecydowałem się na natywne obietnice ES6.

W pliku, do którego dzwonię mongoose.connect:

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

[EDYCJA: Dziękuję @SylonZero za wskazanie błędu wydajności w mojej odpowiedzi. Ponieważ ta odpowiedź jest tak bardzo ceniona, czuję się zobowiązany do wprowadzenia tej zmiany i zachęcania do używania bluebirdzamiast rodzimych obietnic. Przeczytaj odpowiedź poniżej, aby uzyskać więcej wykształconych i doświadczonych szczegółów. ]

Hunter Lester
źródło
3
Po zweryfikowaniu benchmarku na stronie: bluebirdjs.com/docs/benchmarks.html @SylonZero, do którego odnosi się @SylonZero, uważam, że jego rozwiązanie zasługuje na głosowanie zamiast pierwszej propozycji. Nadal dziękuję Hunterowi Lesterowi za tę wspaniałą pracę i śledztwo oraz dzielenie się jego odkryciami!
Isak La Fleur
Dziękuję za edycję, dzięki której zdaję sobie sprawę z ogromnego błędu w wykonaniu
Yusuf Kamil AK
72

Chociaż powyższa odpowiedź jest dokładna i działa, musisz wziąć pod uwagę kwestię wydajności, jeśli masz prawdziwą, produkcyjną aplikację Node.

Powyższe rozwiązanie wykorzysta natywne obietnice ES6 - które są 4X wolniejsze niż bluebird w testach porównawczych, które udostępniłem poniżej. Może to radykalnie wpłynąć na wydajność interfejsu API napisanego w Node i używającego MongoDB.

Polecam używanie 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');

Wyniki testów porównawczych

Platforma: (przy użyciu najnowszego Node w momencie pisania)

  • Linux 4.4.0-59-generic x64
  • Node.JS 6.9.4
  • V8 5.1.281.89
  • Procesor Intel (R) Core (TM) i7-6500U @ 2,50 GHz × 4
  • 16 GB RAM z 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
źródło
1
dla mojego zrozumienia: skąd pochodzi twój punkt odniesienia? Czy istnieje konsensus co do tych wyników? Wygląda na to, że wszyscy głosują na domyślną obietnicę ES6, ale chciałbym zagłębić się w kwestie wydajności, o których wspomniałeś.
Zedenem
1
Test porównawczy pochodzi z zestawu testów, które można przeczytać (i zweryfikować) z repozytorium git bluebird - uruchomiłem je ponownie lokalnie, aby uzyskać powyższe wyniki, ponieważ potrzebowałem wyników z 2017 r., Aby podzielić się z innymi. Co ważniejsze, doświadczyłem wzrostu wydajności w naszym własnym API (mam 5 mikro usług i trudny cel skalowalności) i musiałem często podejmować decyzje o użyciu prostych zagnieżdżonych wywołań zwrotnych zamiast obietnic (nadal najszybszych). Osobiście uważam, że testy porównawcze są tylko pierwszym krokiem do podjęcia decyzji, ale nie mogę jeszcze udostępniać moich danych wewnętrznych ... mój cel to 10 000 użytkowników na fizyczną maszynę.
SylonZero
Ponadto głosowanie za głosem nie jest pełnym miernikiem odpowiedzi. Z mojego doświadczenia wynika, że ​​wielu z nich rzadko zagłębia się po rozwiązaniu problemu (lub czyta cokolwiek innego), a wielu programistów, których mentorowałem w przeszłości, musiało nauczyć się wydajności i umiejętności instrumentacji kodu.
SylonZero
1
Dziękuję bardzo za poruszenie kwestii wydajności. Jestem początkującym programistą, mam tylko 2 lata i pragnę tej edukacji. Używam tego w produkcji, więc jeszcze bardziej się cieszę, że to wiem. Jakie są najlepsze sposoby na testowanie programów i fragmentów kodu?
Hunter Lester
1
Hunter, to zależałoby od natury platformy i kodu, ale związane z tym pytaniem: są dwie strony uzyskiwania wglądu - 1. dobre testy do wykorzystania przez generator obciążenia w celu symulacji żądań użytkowników. Używam Apache jMeter do testowania mojego Node API i do generowania obciążenia dla wielu użytkowników. 2. Instrumentacja: w jaki sposób śledzisz poszczególne transakcje. Używam NewRelic do instrumentowania mojego kodu Node - daje on szczegółowy podział każdej transakcji w ms (aż do trasy Express, czasu zapytania Mongo, Redis dla sesji itp.). Mam nadzieję, że to pozwoli Ci zacząć.
SylonZero
2

próbowałeś tego? Na przykład :

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

jeśli utworzysz model z instancji mangusty, której obietnica nie została przedefiniowana - każde zapytanie w tym modelu spowodowałoby ostrzeżenie.

Krishan Kant Sharma
źródło
2

Myślę, że masz swoją odpowiedź, ale używam global.promise z obsługą błędów

// 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
źródło
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;
      }
});

Trzeba mieć połączenie za pomocą obietnicy w najnowszej wersji mangusty [tu jest link] [1] [1]: http://mongoosejs.com/docs/promises.html

Yashwin Munsadwala
źródło
0

Po prostu dodaj drugi parametr jako obiekt do metody connect ().

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

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

Aaman
źródło
Samo to nie usuwa ostrzeżenia. Musimy również zaplanować globalną obietnicę, jak wspomniano powyżej.
Balasubramani M
0

Mangusta 4.8.6

Jeśli zauważysz taki błąd:

(węzeł: 9600) Przestarzałe Ostrzeżenie: Mongoose: mpromise (domyślna biblioteka obietnic mongoose) jest przestarzała, zamiast tego podłącz własną bibliotekę obietnic: http://mongoosejs.com/docs/promises.html

Musisz także ustawić opcje, które obiecują bibliotekę do wykorzystania przez sterownik.

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

ta praca dla mnie.

Sigit Kuncoro
źródło