Mongoose: Méthodes de collecte obsolètes de mongodb

Créé le 17 août 2018  ·  28Commentaires  ·  Source: Automattic/mongoose

Vous souhaitez demander une fonctionnalité ou signaler un bug ?

Punaise

Quel est le comportement actuel ?

Model.findByIdAndUpdate() émet un avertissement d'obsolescence pour mongodb - qui a obsolète collection.findAndModify. Mongodb suggère d'utiliser plutôt findOneAndUpdate, findOneAndReplace ou findOneAndDelete.

collection.ensureIndex est également obsolète - mongodb suggère d'utiliser createIndexes à la place.

Si le comportement actuel est un bogue, veuillez fournir les étapes à reproduire.

L'utilisation de Model.findByIdAndUpdate / findOneAndUpdate pour modifier un document renvoie ces avertissements d'obsolescence.

Quel est le comportement attendu ?

Aucun avertissement de dépréciation !

Veuillez mentionner votre version de node.js, mongoose et MongoDB.

Noeud v10.8.0
mongodb v3.6.2
mangouste v5.2.9

Commentaire le plus utile

Pareil ici. Je reçois également "l'option de recherche [champs] est obsolète et sera supprimée dans une version ultérieure".

Tous les 28 commentaires

Pareil ici. Je reçois également "l'option de recherche [champs] est obsolète et sera supprimée dans une version ultérieure".

(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.

en voici d'autres que j'ai

Relatif au #6165 et peut être reproduit sur le test CI

Vous pouvez spécifier useFindAndModify sur false pour éviter un message de dépréciation partielle. IMO cela devrait être par défaut à false maintenant.

mongoose.set('useFindAndModify', false);

Avertissement : ne définissez pas cette option sur false en production sans test approprié

Cependant, d'autres méthodes obsolètes telles que ensureIndex(es) et update doivent également être remplacées par une nouvelle API. Définir cette option sur false ne résoudra pas ce problème.
Peut-être devrions-nous mettre à jour toutes les méthodes obsolètes et supprimer les options useFindAndModify dans la prochaine version majeure ?

Noter:
Seul MongoDB 3.2+ prend en charge la requête de la série findOneAndUpdate, mais la bibliothèque [email protected] sous-jacente utilise toujours le polyfill findAndModify pour rester compatible avec la version 2.6 , donc faire useFindAndModify par défaut la valeur false ne supprimera pas la prise en charge de MongoDB 3.0 actuellement.

Cependant, cette compatibilité sera définitivement interrompue car ils ont été marqués comme obsolètes depuis [email protected] (il y a très longtemps) et lancent même des messages d'avertissement.

Par conséquent, je suggère que la prochaine version majeure de mongoose (6.x) déprécie la prise en charge de MongoDB 3.0 et adopte toutes les nouvelles API. De plus, MongoDB 3.0 a atteint la fin de vie en février 2018, il y a six mois.

Des pensées?

Pourquoi cela se produit-il donc? Faut-il attendre la prochaine version majeure de mongoose ?

@lpiVasquez c'est parce que le document indique que mongoose 5.x prend en charge MongoDB Server 3.0 .

Pour l'instant, il est prudent d'utiliser simplement la nouvelle API, car l'API sous-jacente gère toujours cela pour nous. Cependant, cela ne fonctionnera pas une fois que la bibliothèque sous-jacente aura modifié ce comportement et nous devons être très prudents lors de la mise à niveau de la bibliothèque sous-jacente.

Ce que je veux dire, c'est ne pas ignorer le problème, mais abandonner la prise en charge de MongoDB Server 3.0 dans la prochaine version 5.3. Au moins ne cassez pas en 5.2. Juste mon avis cependant.

@IpiVasquez

si par,

Pourquoi cela arrive-t-il?

tu veux dire,

pourquoi mongodb déprécie-t-il ces API

Mongodb a mis en place un plan pour rendre les différentes API de pilotes plus cohérentes. Ceci est documenté ici dans la spécification mongodb crud

Faut-il attendre la prochaine version majeure de mongoose ?

Si nous nous en tenons à la spécification semver , alors tout ce qui casse l'API devrait se produire dans une version MAJEURE , comme @6.0.0 par opposition à une version mineure comme @5.3.0 ou une version de correctif comme @5.2.10 .

En regardant l'historique du pilote natif, je ne m'attendrais pas à ce qu'ils suppriment ces méthodes avant la v4 du pilote.

En attendant, je pense que la plupart des avertissements d'obsolescence que j'ai vus jusqu'à présent peuvent être atténués en mode utilisateur en n'appelant pas les méthodes obsolètes. Je suppose que la plupart de ces méthodes seront supprimées dans mangouste @6.0.0 toute façon.

Je pense que les 2 principaux problèmes que nous devons traiter dans la mangouste le plus tôt possible sont de remplacer projections par fields dans les options de requête (fonctionne au moins à la version 3.0.15 du serveur) et de changer potentiellement la valeur par défaut de useFindAndModify telle que décrite par @Fonger , avec un addendum :

findOneAndUpdate dans le pilote natif appellera findAndModify pour vous en interne (sans l'avertissement d'obsolescence) lorsque vous êtes connecté à un serveur antérieur à 3.2, donc findOneAndUpdate dans mangouste fonctionne toujours avec mongodb antérieur à 3.2 et useFindAndModify: false comme le montre cet exemple :

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();

Sortir:

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

Vous pouvez également le démontrer avec uniquement le pilote natif comme ceci :

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);
}

Sortie tronquée :

...
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' }

Pareil ici. J'ai eu cet avertissement au démarrage de l'application :

(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.

Si vous trouvez l'avertissement d'obsolescence ennuyeux, comme solution de contournement _temporaire_ , vous pouvez démarrer le processus node.js en cli avec --no-deprecation pour supprimer l'avertissement. Il est cependant _non recommandé_ de le faire.

avec le mien:

 (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.

aimer package-lock.json plus que jamais...

Il existe plusieurs solutions pour contourner ces avertissements d'obsolescence :

1) Re : findOneAndUpdate() et findAndModify() , utilisez mongoose.set('useFindAndModify', false);
2) Re : remove() obsolescence, passez à l'utilisation deleteOne() ou deleteMany() selon que vous ne souhaitez supprimer qu'un seul document
3) Re : update() obsolète, remplacer par updateMany()

Nous ajouterons quelques documents pour aider les gens à nettoyer ces avertissements d'obsolescence et apporterons des modifications internes afin que la mangouste ne provoque pas l'un de ces avertissements d'obsolescence.

Peut-être devons-nous mettre à jour toutes les méthodes obsolètes et supprimer les options useFindAndModify dans la prochaine version majeure ?

Je serais en faveur de cela 👍

Mongoose prend-il déjà en charge les nouvelles méthodes, deleteOne() , deleteMany() , updateMany() etc?

+1
même avertissement. nous devons attendre un nouveau chauffeur.

alors comme, en ce moment, nous devons ignorer ces avertissements ? Je veux dire que j'essaie de créer une API, où j'ai besoin de tout obtenir de la base de données et chaque fois que j'appelle collection.find().then()....etc, cela me donne le même avertissement. que puis-je faire pour remplacer cette méthode find() ?

Si vous êtes simplement gêné par les avertissements, vous pouvez probablement désactiver les avis de dépréciation dans Node (voir le commentaire de Fonger ci-dessus), ou vous pouvez revenir à une ancienne version de Mongoose.

Alors qu'est-ce que je dois faire?

J'ai reçu ce message d'avertissement de la mangouste chaque fois que j'exécute une requête de recherche. Je vais l'ignorer jusqu'à la prochaine mise à jour de l'équipe de la mangouste.

(node:15500) DeprecationWarning : l'option collection.find [fields] est obsolète et sera supprimée dans une version ultérieure.

Le correctif pour l'avertissement de dépréciation fields sera dans 5.2.10, vous ne le verrez plus. Pour nettoyer les autres avertissements de dépréciation, suivez les instructions de ce commentaire : https://github.com/Automattic/mongoose/issues/6922#issue -354147871

Merci d'avoir écrit ce document https://mongoosejs.com/docs/deprecations.html

Re : findOneAndUpdate() et findAndModify() obsolescence, la seule solution de contournement actuelle ( 5.2.17 ) consiste à définir :

mongoose.set('useFindAndModify', false);

Est-ce vrai?

J'utilise Model.findByIdAndUpdate() et Model.findOneAndUpdate()

Je suppose que les fonctions sous-jacentes du pilote mongo db utilisées par mongoose seront / devraient être mises à jour à un moment donné.
Aurais-je raison ?

+1 J'ai le même avertissement d'obsolescence pour l'utilisation de Model.findByIdAndUpdate();

J'utilise les versions suivantes :

  • mongodb : 3.1.4
  • mangouste : 5.2.16

Des nouvelles à ce sujet ?

@gianpaj oui mongoose.set('useFindAndModify', false) est la seule solution de contournement actuelle pour l'avertissement d'obsolescence findAndModify. Je suppose que l'appel sous-jacent à collection.findAndModify() disparaîtra dans [email protected]. @vkarpov15 est-ce que ça sonne bien ? ou est-il trop tôt pour s'engager sur un laps de temps ?

@daniyalawan consultez la documentation ici l'option 'useFindAndModify' s'applique à vous si vous appelez findOneAndUpdate dans votre code (cela s'étend à findByIdAndUpdate car il appelle findOneAndUpdate en interne).

@Sastidar quel(s) problème(s) rencontrez-vous après la mise à niveau vers [email protected] ? Tous les avertissements d'obsolescence doivent être traités dans ces documents

@lineus @gianpaj oui, le besoin de l'option useFindAndModify disparaîtra avec Mongoose 6.0.0. Pas de calendrier pour la sortie de Mongoose 6.

Concernant l'avertissement de dépréciation - Mongoose supprimera-t-il progressivement la possibilité d'utiliser la méthode findByIdAndUpdate ou le findAndModify sous-jacent sera-t-il simplement supprimé sans tuer mon implémentation ?

Je demande essentiellement si je change tous mes findByIdAndUpdate en findOneAndUpdate avant d'avoir une base de code plus grande.

@gianpaj oui mongoose.set('useFindAndModify', false) est la seule solution de contournement actuelle pour l'avertissement d'obsolescence findAndModify. Je suppose que l'appel sous-jacent à collection.findAndModify() disparaîtra dans [email protected]. @vkarpov15 est-ce que ça sonne bien ? ou est-il trop tôt pour s'engager sur un laps de temps ?

@daniyalawan consultez la documentation ici l'option 'useFindAndModify' s'applique à vous si vous appelez findOneAndUpdate dans votre code (cela s'étend à findByIdAndUpdate car il appelle findOneAndUpdate en interne).

@Sastidar quel(s) problème(s) rencontrez-vous après la mise à niveau vers [email protected] ? Tous les avertissements d'obsolescence doivent être traités dans ces documents

{new: true} ne fonctionnera pas si j'utilise mongoose.set('useFindAndModify', false) . une autre option?

@ anks333 l'exemple suivant fonctionne pour moi. Pouvez-vous le modifier pour montrer { new: true } ne fonctionne pas ?

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();

Sortir:

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

@LBWright, nous n'avons pas l'intention d'abandonner la prise en charge de findByIdAndUpdate, nous allons simplement échanger le findAndModify sous-jacent sans casser l'API

(node:10767) DeprecationWarning : collection.ensureIndex est obsolète. Utilisez plutôt createIndexes.

Cette page vous a été utile?
0 / 5 - 0 notes