Mongoose: Устаревшие методы сбора из mongodb

Созданный на 17 авг. 2018  ·  28Комментарии  ·  Источник: Automattic/mongoose

Вы хотите запросить функцию или сообщить об ошибке ?

Ошибка

Каково текущее поведение?

Model.findByIdAndUpdate() выдает предупреждение об устаревании для mongodb, которое устарело для collection.findAndModify. Mongodb предлагает вместо этого использовать findOneAndUpdate, findOneAndReplace или findOneAndDelete.

collection.ensureIndex также устарел — вместо этого mongodb предлагает использовать createIndexes.

Если текущее поведение является ошибкой, предоставьте шаги для воспроизведения.

Использование Model.findByIdAndUpdate/findOneAndUpdate для изменения документа возвращает эти предупреждения об устаревании.

Каково ожидаемое поведение?

Никаких предупреждений об устаревании!

Пожалуйста, укажите вашу версию node.js, mongoose и MongoDB.

Узел v10.8.0
монгодб v3.6.2
мангуст v5.2.9

Самый полезный комментарий

То же самое. Я также получаю «параметр поиска [поля] устарел и будет удален в более поздней версии».

Все 28 Комментарий

То же самое. Я также получаю «параметр поиска [поля] устарел и будет удален в более поздней версии».

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

Вот другие, которые у меня есть

Связан с # 6165 и может быть воспроизведен в тесте CI

Вы можете указать для useFindAndModify значение false , чтобы предотвратить сообщение о частичном устаревании. IMO, теперь по умолчанию должно быть установлено значение false.

mongoose.set('useFindAndModify', false);

Предупреждение: не устанавливайте для этого параметра значение false в рабочей среде без надлежащего тестирования.

Однако другие устаревшие методы, такие как ensureIndex(es) и update , также необходимо заменить новым API. Установка для этого параметра значения false не исправит это.
Может быть, нам нужно обновить все устаревшие методы и удалить опции useFindAndModify в следующем основном выпуске?

Примечание:
Только MongoDB 3.2+ поддерживает серийный запрос findOneAndUpdate, но базовая библиотека [email protected] по-прежнему использует полифиллы findAndModify, чтобы сохранить совместимость с версией 2.6 , поэтому установка useFindAndModify по умолчанию на false не приведет к прекращению поддержки MongoDB 3.0 в настоящее время.

Однако эта совместимость определенно скоро сломается, поскольку они были помечены как устаревшие с [email protected] (очень давно) и теперь даже выдают предупреждающие сообщения.

Следовательно, я предлагаю в следующем крупном выпуске mongoose (6.x) отказаться от поддержки MongoDB 3.0 и принять все новые API. Кроме того, срок службы MongoDB 3.0 истек в феврале 2018 года, полгода назад.

Есть предположения?

Итак... почему это происходит? Нужно ли ждать следующего крупного релиза мангуста?

@lpiVasquez это потому, что в документе говорится, что mongoose 5.x поддерживает MongoDB Server 3.0 .

На данный момент безопасно просто использовать новый API, потому что базовый API по-прежнему обрабатывает это за нас. Однако это не сработает, как только базовая библиотека изменит это поведение, и нам нужно быть очень осторожными при обновлении базовой библиотеки.

Я имею в виду не игнорирование проблемы, а отказ от поддержки MongoDB Server 3.0 в следующем выпуске 5.3. По крайней мере, не ломайте 5.2. Только мое мнение.

@IpiVasquez

если по,

почему это происходит?

ты имеешь в виду,

почему mongodb не поддерживает эти API

У Mongodb есть план, чтобы сделать различные API-интерфейсы драйверов более согласованными. Это задокументировано здесь, в спецификации mongodb crud.

Нужно ли ждать следующего крупного релиза мангуста?

Если мы придерживаемся спецификации semver , то все, что нарушает API, должно произойти в ОСНОВНОМ выпуске, например, @6.0.0 , а не в второстепенном выпуске, таком как @5.3.0 , или выпуске исправления , например @5.2.10 .

Оглядываясь назад на историю родного драйвера, я бы не ожидал, что они удалят эти методы до версии 4 драйвера.

В то же время я думаю, что большинство предупреждений об устаревании, которые я видел до сих пор, можно смягчить в пространстве пользователя, не вызывая устаревшие методы. Я предполагаю, что большинство этих методов все равно будут удалены в мангусте @6.0.0 .

Я думаю, что две основные проблемы, с которыми нам нужно разобраться в мангусте раньше, чем позже, - это замена projections на fields в параметрах запроса (работает как минимум до версии сервера 3.0.15) и потенциальное изменение значение по умолчанию useFindAndModify , как описано @Fonger , с одним дополнением:

findOneAndUpdate в собственном драйвере будет вызывать findAndModify для вас внутри (без предупреждения об устаревании), когда вы подключены к серверу до 3.2, поэтому findOneAndUpdate в mongoose по-прежнему работает с mongodb до 3.2 и useFindAndModify: false как показано в этом примере:

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

Вывод:

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

Вы также можете продемонстрировать это только с помощью собственного драйвера, например:

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

усеченный вывод:

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

То же самое. Я получил это предупреждение при запуске приложения:

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

Если вас раздражает предупреждение об устаревании, в качестве _временного_ обходного пути вы можете запустить процесс node.js в cli с --no-deprecation , чтобы подавить предупреждение. Однако делать это _не рекомендуется_.

с моими:

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

люблю package-lock.json больше, чем когда-либо...

Есть несколько обходных путей, чтобы обойти эти предупреждения об устаревании:

1) Re: findOneAndUpdate() и findAndModify() устаревают, используйте mongoose.set('useFindAndModify', false);
2) Re: Устаревание remove() , переключитесь на использование deleteOne() или deleteMany() в зависимости от того, хотите ли вы удалить только один документ.
3) Re: update() устарело, заменить на updateMany()

Мы добавим некоторые документы, чтобы помочь людям очистить эти предупреждения об устаревании, и внесем некоторые внутренние изменения, чтобы мангуст не вызывал одно из этих предупреждений об устаревании.

Может быть, нам нужно обновить все устаревшие методы и удалить параметры useFindAndModify в следующем основном выпуске?

Я бы за это 👍

У мангуста уже есть поддержка новых методов, deleteOne() , deleteMany() , updateMany() и т. д.?

+1
такое же предупреждение. нам нужно ждать нового водителя.

так что, прямо сейчас мы должны игнорировать эти предупреждения? я имею в виду, что я пытаюсь создать API, где мне нужно получить все из БД, и всякий раз, когда я вызываю collection.find().then()....и т. д., он дает мне такое же предупреждение. что я могу сделать, чтобы заменить этот метод find ()?

Если вас просто беспокоят предупреждения, вы, вероятно, можете отключить уведомления об устаревании в Node (см. комментарий Фонгера выше) или вернуться к более старой версии Mongoose.

Итак, что мне нужно сделать?

Получал это предупреждающее сообщение от мангуста каждый раз, когда запускаю запрос на поиск. Буду игнорировать это до следующего обновления от команды мангустов.

(узел: 15500) Предупреждение об устаревании: опция collection.find [поля] устарела и будет удалена в более поздней версии.

Исправление для предупреждения об устаревании fields будет в 5.2.10, вы его больше не увидите. Чтобы убрать другие предупреждения об устаревании, следуйте инструкциям в этом комментарии: https://github.com/Automattic/mongoose/issues/6922#issue -354147871.

Спасибо за написание этого документа https://mongoosejs.com/docs/deprecations.html.

Re: findOneAndUpdate() и findAndModify() устарели, единственным текущим ( 5.2.17 ) обходным решением является установка:

mongoose.set('useFindAndModify', false);

это правда?

Я использую Model.findByIdAndUpdate() и Model.findOneAndUpdate()

Я предполагаю, что базовые функции драйвера mongo db, используемые mongoose, будут / должны быть обновлены в какой-то момент.
Был бы я прав?

+1 У меня такое же предупреждение об устаревании для использования Model.findByIdAndUpdate();

Я использую следующие версии:

  • монгодб: 3.1.4
  • мангуст: 5.2.16

Есть новости по этому поводу?

@gianpaj yes mongoose.set('useFindAndModify', false) — единственный текущий обходной путь для предупреждения об устаревании findAndModify. Я предполагаю , что основной вызов collection.findAndModify() исчезнет в [email protected]. @vkarpov15 это звучит правильно? или еще рано говорить о сроках?

@daniyalawan ознакомьтесь с документами здесь . Параметр «useFindAndModify» применяется к вам, если вы вызываете findOneAndUpdate в своем коде (это распространяется на findByIdAndUpdate, поскольку он вызывает findOneAndUpdate внутри).

@Sastidar, какие проблемы у вас возникли после обновления до [email protected]? Все предупреждения об устаревании должны быть рассмотрены в этих документах.

@lineus @gianpaj да, необходимость в опции useFindAndModify исчезнет с Mongoose 6.0.0. Сроков, когда мы выпустим Mongoose 6, нет.

Что касается предупреждения об устаревании. Будет ли mongoose постепенно отказываться от возможности использовать метод findByIdAndUpdate или базовый findAndModify просто будет прекращен без уничтожения моей реализации?

В основном я спрашиваю, могу ли я изменить все свои findByIdAndUpdate на findOneAndUpdate , прежде чем у меня будет большая кодовая база.

@gianpaj yes mongoose.set('useFindAndModify', false) — единственный текущий обходной путь для предупреждения об устаревании findAndModify. Я предполагаю , что основной вызов collection.findAndModify() исчезнет в [email protected]. @vkarpov15 это звучит правильно? или еще рано говорить о сроках?

@daniyalawan ознакомьтесь с документами здесь . Параметр «useFindAndModify» применяется к вам, если вы вызываете findOneAndUpdate в своем коде (это распространяется на findByIdAndUpdate, поскольку он вызывает findOneAndUpdate внутри).

@Sastidar, какие проблемы у вас возникли после обновления до [email protected]? Все предупреждения об устаревании должны быть рассмотрены в этих документах.

{new: true} не будет работать, если я использую mongoose.set('useFindAndModify', false) . любой другой вариант?

@anks333 у меня работает следующий пример. Можете ли вы изменить его, чтобы показать, что { new: true } не работает?

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

Вывод:

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

@LBWright мы не собираемся отказываться от поддержки findByIdAndUpdate, мы просто заменим базовый findAndModify, не нарушая API

(узел: 10767) Предупреждение об устаревании: collection.ensureIndex устарел. Вместо этого используйте createIndexes.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги