Mongoose: Veraltete Erfassungsmethoden von mongodb

Erstellt am 17. Aug. 2018  ·  28Kommentare  ·  Quelle: Automattic/mongoose

Möchten Sie eine Funktion anfordern oder einen Fehler melden?

Insekt

Wie ist das aktuelle Verhalten?

Model.findByIdAndUpdate() gibt eine Verfallswarnung für mongodb aus – die collection.findAndModify als veraltet markiert hat. Mongodb schlägt vor, stattdessen findOneAndUpdate, findOneAndReplace oder findOneAndDelete zu verwenden.

collection.ensureIndex ist ebenfalls veraltet – mongodb schlägt vor, stattdessen createIndexes zu verwenden.

Wenn es sich bei dem aktuellen Verhalten um einen Fehler handelt, geben Sie bitte die Schritte zum Reproduzieren an.

Die Verwendung von Model.findByIdAndUpdate / findOneAndUpdate zum Ändern eines Dokuments gibt diese Verfallswarnungen zurück.

Was ist das erwartete Verhalten?

Keine Abwertungswarnungen!

Bitte geben Sie Ihre node.js-, Mongoose- und MongoDB-Version an.

Knoten v10.8.0
mongodb v3.6.2
Mungo v5.2.9

Hilfreichster Kommentar

Hier gilt das gleiche. Ich erhalte auch "Suchoption [Felder] ist veraltet und wird in einer späteren Version entfernt."

Alle 28 Kommentare

Hier gilt das gleiche. Ich erhalte auch "Suchoption [Felder] ist veraltet und wird in einer späteren Version entfernt."

(node:13076) DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead.
(node:13076) DeprecationWarning: collection.remove is deprecated. Use deleteOne, deleteMany, or bulkWrite instead.
(node:13076) DeprecationWarning: collection.find option [fields] is deprecated and will be removed in a later version.
(node:13076) DeprecationWarning: collection.update is deprecated. Use updateOne, updateMany, or bulkWrite instead.

Hier sind einige andere, die ich habe

Verwandt mit #6165 und kann im CI-Test reproduziert werden

Sie können useFindAndModify auf „false“ setzen , um eine Meldung zur teilweisen Verwerfung zu verhindern. IMO sollte dies jetzt standardmäßig auf "false" stehen.

mongoose.set('useFindAndModify', false);

Warnung: Setzen Sie diese Option in der Produktion nicht ohne ordnungsgemäße Tests auf „false“.

Andere veraltete Methoden wie ensureIndex(es) und update müssen jedoch auch noch durch eine neue API ersetzt werden. Wenn Sie diese Option auf „false“ setzen, wird dies nicht behoben.
Vielleicht müssen wir alle veralteten Methoden aktualisieren und useFindAndModify -Optionen in der nächsten Hauptversion entfernen?

Notiz:
Nur MongoDB 3.2+ unterstützt Abfragen der findOneAndUpdate-Serie, aber die zugrunde liegende [email protected] -Bibliothek verwendet immer noch findAndModify-Polyfill, um die Kompatibilität mit 2.6 aufrechtzuerhalten. Wenn Sie also useFindAndModify standardmäßig auf „false“ festlegen, wird die Unterstützung für MongoDB 3.0 derzeit nicht wirklich eingestellt.

Diese Kompatibilität wird jedoch definitiv bald unterbrochen, da sie seit [email protected] (vor sehr langer Zeit) als veraltet markiert wurden und jetzt sogar Warnmeldungen ausgeben.

Daher schlage ich vor, dass die nächste Hauptversion von Mongoose (6.x) die MongoDB 3.0-Unterstützung aufgibt und eine völlig neue API übernimmt. Außerdem hat MongoDB 3.0 im Februar 2018, also vor einem halben Jahr, das End-of-Life erreicht.

Irgendwelche Gedanken?

Also ... warum passiert das? Muss man bis zum nächsten Mongoose-Major-Release warten?

@lpiVasquez , weil das Dokument besagt, dass Mongoose 5.x MongoDB Server 3.0 unterstützt .

Im Moment ist es sicher, nur die neue API zu verwenden, da die zugrunde liegende API dies immer noch für uns übernimmt. Es funktioniert jedoch nicht, wenn die zugrunde liegende Bibliothek dieses Verhalten ändert, und wir müssen beim Aktualisieren der zugrunde liegenden Bibliothek sehr vorsichtig sein.

Damit meine ich nicht, das Problem zu ignorieren, sondern die Unterstützung für MongoDB Server 3.0 in der nächsten Version 5.3 einzustellen. Wenigstens nicht in 5.2 einbrechen. Allerdings nur meine Meinung.

@IpiVasquez

wenn durch,

warum passiert das?

was meinen Sie,

Warum lehnt Mongodb diese APIs ab

Mongodb hat einen Plan, um die verschiedenen Treiber-APIs konsistenter zu machen. Dies ist hier in der Crud-Spezifikation von Mongodb dokumentiert

Muss man bis zum nächsten Mongoose-Major-Release warten?

Wenn wir uns an die Semver-Spezifikation halten , sollte alles, was die API unterbricht, in einer MAJOR- Version wie @6.0.0 passieren, im Gegensatz zu einer Nebenversion wie @5.3.0 oder einer Patch -Version wie @5.2.10 .

Wenn ich auf die Geschichte des nativen Treibers zurückblicke, würde ich nicht erwarten, dass sie diese Methoden bis v4 des Treibers entfernen.

In der Zwischenzeit denke ich, dass die meisten der Verfallswarnungen, die ich bisher gesehen habe, im Userland abgemildert werden können, indem veraltete Methoden nicht aufgerufen werden. Ich vermute, dass die meisten dieser Methoden sowieso in Mongoose @6.0.0 entfernt werden.

Ich denke, die 2 Hauptprobleme, mit denen wir uns in Mungo eher früher als später befassen müssen, sind das Ersetzen projections durch fields in Abfrageoptionen (funktioniert zurück bis mindestens Serverversion 3.0.15) und möglicherweise Änderungen der Standardwert von useFindAndModify wie von @Fonger beschrieben, mit einem Zusatz:

findOneAndUpdate im nativen Treiber ruft findAndModify intern für Sie auf ( ohne die Verfallswarnung ), wenn Sie mit einem Server vor 3.2 verbunden sind, sodass findOneAndUpdate in Mongoose immer noch mit mongodb vor 3.2 und useFindAndModify: false funktioniert wie in diesem Beispiel gezeigt:

6880.js

#!/usr/bin/env node
'use strict';

const mongoose = require('mongoose');
mongoose.set('useFindAndModify', false);

const url = 'mongodb://localhost:27017/test';
const opts = { useNewUrlParser: true };

mongoose.connect(url, opts);
const conn = mongoose.connection;
const Schema = mongoose.Schema;

const schema = new Schema({
  name: String
});

const Test = mongoose.model('test', schema);

async function run() {
  await conn.dropDatabase();
  let admin = conn.db.admin();
  let { version } = await admin.serverInfo();
  console.log(`mongodb: ${version}`);
  console.log(`mongoose: ${mongoose.version}`);

  let cond = {};
  let update = { name: 'Sarah' };
  let opts = {
    upsert: true,
    new: true
  };

  let sarah = await Test.findOneAndUpdate(cond, update, opts);
  console.log(sarah);
  return conn.close();
}

run();

Ausgabe:

issues: ./6880.js
mongodb: 3.0.15
mongoose: 5.2.9
{ _id: 5b779ca8d1326ce227b6869f, __v: 0, name: 'Sarah' }
issues:

Sie können dies auch nur mit dem nativen Treiber wie folgt demonstrieren:

6880_native.js

#!/usr/bin/env node
'use strict';

const { MongoClient, Logger } = require('mongodb');

const uri = 'mongodb://localhost:27017/test';
const opts = { 
  useNewUrlParser: true
};

async function run() {
  const client = new MongoClient(uri, opts);
  await client.connect();
  const db = client.db('gh-6881');
  await db.dropDatabase().catch(handleError);

  Logger.setLevel('debug');
  let res = await db
    .collection('tests')
    .findOneAndUpdate({}, { $set: { name: 'michael' } }, { upsert: true })
    .catch(handleError);
  Logger.setLevel('error');
  console.log(res);
  let doc = await db
    .collection('tests')
    .findOne({})
    .catch(handleError);

  console.log(doc);
  process.exit(0);
}

run();

function handleError(e) {
  return console.error(e.message);
}

abgeschnittene Ausgabe:

...
message: 'executing command [{"ns":"gh-6881.$cmd","cmd":{"findAndModify":"tests","query":{},"new":false,"remove":false,"upsert":true,"update":{"$set":{"name":"michael"}}},"options":{}}] against localhost:27017',
...
{ value: null,
  lastErrorObject:
   { updatedExisting: false,
     n: 1,
     upserted: 5b77a23cd1326ce227b686a1 },
  ok: 1 }
{ _id: 5b77a23cd1326ce227b686a1, name: 'michael' }

Hier gilt das gleiche. Ich habe diese Warnung beim Start der Anwendung erhalten:

(node:9856) DeprecationWarning: collection.findAndModify is deprecated. Use findOneAndUpdate, findOneAndReplace or findOneAndDelete instead.
(node:9856) DeprecationWarning: collection.find option [fields] is deprecated and will be removed in a later version.
(node:9856) DeprecationWarning: collection.find option [fields] is deprecated and will be removed in a later version.

Wenn Sie eine Verfallswarnung als lästig empfinden, können Sie als _vorübergehende_ Problemumgehung den node.js-Prozess in cli mit --no-deprecation starten, um die Warnung zu unterdrücken. Es wird jedoch _nicht empfohlen_, dies zu tun.

mit meiner:

 (node:1) DeprecationWarning: collection.findAndModify is deprecated. Use findOneAndUpdate, findOneAndReplace or findOneAndDelete instead.
 (node:1) DeprecationWarning: collection.remove is deprecated. Use deleteOne, deleteMany, or bulkWrite instead.
(node:1) DeprecationWarning: collection.update is deprecated. Use updateOne, updateMany, or bulkWrite instead.
 (node:1) DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead.
(node:1) DeprecationWarning: collection.find option [fields] is deprecated and will be removed in a later version.
(node:1) DeprecationWarning: collection.find option [fields] is deprecated and will be removed in a later version.

liebe package-lock.json mehr als je zuvor ...

Es gibt mehrere Problemumgehungen, um diese Verfallswarnungen zu umgehen:

1) Re: findOneAndUpdate() und findAndModify() veraltet, verwenden Sie mongoose.set('useFindAndModify', false);
2) Betreff: remove() Verfall, wechseln Sie zu deleteOne() oder deleteMany() , je nachdem, ob Sie nur ein Dokument löschen möchten
3) Betreff: update() Abwertung, durch updateMany() ersetzen

Wir werden einige Dokumente hinzufügen, um den Benutzern zu helfen, diese Verfallswarnungen zu bereinigen, und einige interne Änderungen vornehmen, damit Mongoose keine dieser Verfallswarnungen verursacht.

Vielleicht müssen wir alle veralteten Methoden aktualisieren und useFindAndModify-Optionen in der nächsten Hauptversion entfernen?

Ich wäre dafür 👍

Unterstützt Mongoose bereits die neuen Methoden deleteOne() , deleteMany() , updateMany() usw.?

+1
dieselbe Warnung. Wir müssen auf einen neuen Fahrer warten.

Also, im Moment müssen wir diese Warnungen ignorieren? Ich meine, ich versuche, eine API zu erstellen, wo ich alles von db bekommen muss und wann immer ich collection.find().then()....etc aufrufe, gibt es mir dieselbe Warnung. Was kann ich tun, um diese Methode find () zu ersetzen?

Wenn Sie nur die Warnungen stören, können Sie wahrscheinlich die Verfallshinweise in Node deaktivieren (siehe Fongers Kommentar oben) oder zu einer älteren Version von Mongoose zurückkehren.

Also, was muss ich tun?

Ich habe diese Warnmeldung von Mungo jedes Mal erhalten, wenn ich eine Suchabfrage ausführe. Ich werde es bis nach dem nächsten Update vom Mongoose-Team ignorieren.

(node:15500) DeprecationWarning: collection.find option [fields] ist veraltet und wird in einer späteren Version entfernt.

Der Fix für die fields Verfallswarnung wird in 5.2.10 sein, Sie werden ihn nicht mehr sehen. Befolgen Sie die Anweisungen in diesem Kommentar, um die anderen Verfallswarnungen zu bereinigen: https://github.com/Automattic/mongoose/issues/6922#issue -354147871

Vielen Dank für das Schreiben dieses Dokuments https://mongoosejs.com/docs/deprecations.html

Re: findOneAndUpdate() und findAndModify() veraltet, die einzige aktuelle Problemumgehung ( 5.2.17 ) besteht darin, Folgendes festzulegen:

mongoose.set('useFindAndModify', false);

ist das wahr?

Ich verwende Model.findByIdAndUpdate() und Model.findOneAndUpdate()

Ich gehe davon aus, dass die zugrunde liegenden Mongo-DB-Treiberfunktionen, die von Mongoose verwendet werden, irgendwann aktualisiert werden / sollten.
Hätte ich Recht?

+1 Ich habe dieselbe Verfallswarnung für die Verwendung von Model.findByIdAndUpdate();

Ich verwende folgende Versionen:

  • mongodb: 3.1.4
  • Mungo: 5.2.16

Gibt es Neuigkeiten zu diesem Thema ?

@gianpaj ja mongoose.set('useFindAndModify', false) ist die einzige aktuelle Problemumgehung für die Verfallswarnung von findAndModify. Ich vermute , dass der zugrunde liegende Aufruf von collection.findAndModify() in [email protected] verschwindet. @vkarpov15 klingt das ungefähr richtig? oder ist es zu früh, sich auf einen Zeitrahmen festzulegen?

@daniyalawan sehen Sie sich die Dokumentation hier an. Die Option 'useFindAndModify' gilt für Sie, wenn Sie findOneAndUpdate in Ihrem Code aufrufen (dies erstreckt sich auf findByIdAndUpdate, da es intern findOneAndUpdate aufruft).

@Sastidar , welche Probleme haben Sie nach dem Upgrade auf [email protected]? Alle Verwerfungswarnungen sollten in diesen Dokumenten behandelt werden

@lineus @gianpaj ja, die useFindAndModify-Option wird mit Mongoose 6.0.0 wegfallen. Kein Zeitrahmen für die Veröffentlichung von Mongoose 6.

In Bezug auf die Verfallswarnung - Wird Mongoose die Fähigkeit zur Verwendung der findByIdAndUpdate -Methode auslaufen lassen oder wird die zugrunde liegende findAndModify $-Methode einfach auslaufen, ohne meine Implementierung zu beenden?

Ich frage im Grunde, ob ich alle meine findByIdAndUpdate in findOneAndUpdate ändere, bevor ich eine größere Codebasis habe.

@gianpaj ja mongoose.set('useFindAndModify', false) ist die einzige aktuelle Problemumgehung für die Verfallswarnung von findAndModify. Ich vermute , dass der zugrunde liegende Aufruf von collection.findAndModify() in [email protected] verschwindet. @vkarpov15 klingt das ungefähr richtig? oder ist es zu früh, sich auf einen Zeitrahmen festzulegen?

@daniyalawan sehen Sie sich die Dokumentation hier an. Die Option 'useFindAndModify' gilt für Sie, wenn Sie findOneAndUpdate in Ihrem Code aufrufen (dies erstreckt sich auf findByIdAndUpdate, da es intern findOneAndUpdate aufruft).

@Sastidar , welche Probleme haben Sie nach dem Upgrade auf [email protected]? Alle Verwerfungswarnungen sollten in diesen Dokumenten behandelt werden

{new: true} funktioniert nicht, wenn ich mongoose.set('useFindAndModify', false) verwende. irgendeine andere Möglichkeit?

@ anks333 das folgende Beispiel funktioniert für mich. Können Sie es ändern, um anzuzeigen, dass { new: true } nicht funktioniert?

6880.js

#!/usr/bin/env node
'use strict';

const assert = require('assert');
const mongoose = require('mongoose');
mongoose.set('useFindAndModify', false);
const { Schema, connection} = mongoose;
const DB = '6880';
const URI = `mongodb://localhost:27017/${DB}`;
const OPTS = { family: 4, useNewUrlParser: true };

const schema = new Schema({
  name: String
});

const Test = mongoose.model('test', schema);

const test = new Test({ name: 'test1' });

async function run() {
  await mongoose.connect(URI, OPTS);
  await connection.dropDatabase();
  const doc = await Test.create(test);
  assert.ok(doc);
  const cond = {};
  const update = { name: 'test2' };
  const options = { new: true };
  const updated = await Test.findOneAndUpdate(cond, update, options);
  assert.strictEqual(updated.name, 'test2');
  console.log('All Assertions Pass.');
  await connection.close();
}

run();

Ausgabe:

issues: ./6880.js
All Assertions Pass.
issues:

@LBWright Wir haben nicht die Absicht, die Unterstützung für findByIdAndUpdate einzustellen, wir tauschen einfach das zugrunde liegende findAndModify aus, ohne die API zu beschädigen

(node:10767) DeprecationWarning: collection.ensureIndex ist veraltet. Verwenden Sie stattdessen createIndexes.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen