Spec-Zone.ru › Mongoose

Миграция с 6.x на 7.x

При миграции с Mongoose 6.x на Mongoose 7.x следует учитывать несколько изменений, которые могут повлиять на обратную совместимость.

Если вы всё ещё используете Mongoose 5.x, пожалуйста, прочтите руководство по миграции с Mongoose 5.x на 6.x справочник по миграции и обновитесь до Mongoose 6.x в первую очередь.

  • strictQuery
  • Удален remove()
  • Отсутствует поддержка обратного вызова
  • Удален update()
  • Схемы дискриминатора по умолчанию используют опции базовой схемы
  • Удален castForQueryWrapper(), обновлена сигнатура castForQuery()
  • Копирование опций схемы в Schema.prototype.add()
  • ObjectId bsontype теперь имеет строчную букву d
  • Удалена поддержка пользовательских библиотек обещаний
  • Удалена mapReduce
  • Изменения, специфичные для TypeScript
    • Удален LeanDocument и поддержка extends Document
    • Новые параметры для HydratedDocument

strictQuery

strictQuery теперь по умолчанию имеет значение false.

const mySchema = new Schema({ field: Number });
const MyModel = mongoose.model('Test', mySchema);

// Mongoose will not strip out `notInSchema: 1` because `strictQuery` is false by default
const docs = await MyModel.find({ notInSchema: 1 });
// Empty array in Mongoose 7. In Mongoose 6, this would contain all documents in MyModel
docs;

Удален remove()

Метод remove() для документов и моделей был удален. Используйте deleteOne() или deleteMany() вместо него.

const mySchema = new Schema({ field: Number });
const MyModel = mongoose.model('Test', mySchema);

// Change this:
await MyModel.remove(filter);

// To this:
await MyModel.deleteOne(filter);
// Or this, if you want to delete multiple:
await MyModel.deleteMany(filter);

// For documents, change this:
await doc.remove();

// To this:
await doc.deleteOne();

Обратите внимание, что хуки deleteOne() по умолчанию обрабатываются как middleware запросов. Для middleware выполните следующее:

// Replace this:
schema.pre('remove', function() {
  /* ... */
});

// With this:
schema.pre('deleteOne', { document: true, query: false }, function() {
  /* ... */
});

Отсутствует поддержка обратного вызова

Следующие функции больше не принимают обратные вызовы. Они всегда возвращают обещания.

  • Aggregate.prototype.exec
  • Aggregate.prototype.explain
  • AggregationCursor.prototype.close
  • Connection.prototype.startSession
  • Connection.prototype.dropCollection
  • Connection.prototype.createCollection
  • Connection.prototype.dropDatabase
  • Connection.prototype.openUri
  • Connection.prototype.close
  • Connection.prototype.destroy
  • Document.prototype.populate
  • Document.prototype.validate
  • Mongoose.prototype.connect
  • Mongoose.prototype.createConnection
  • Model.prototype.save
  • Model.aggregate
  • Model.bulkWrite
  • Model.cleanIndexes
  • Model.countDocuments
  • Model.create
  • Model.createCollection
  • Model.createIndexes
  • Model.deleteOne
  • Model.deleteMany
  • Model.distinct
  • Model.ensureIndexes
  • Model.estimatedDocumentCount
  • Model.exists
  • Model.find
  • Model.findById
  • Model.findByIdAndUpdate
  • Model.findByIdAndReplace
  • Model.findOne
  • Model.findOneAndDelete
  • Model.findOneAndUpdate
  • Model.findOneAndRemove
  • Model.insertMany
  • Model.listIndexes
  • Model.replaceOne
  • Model.syncIndexes
  • Model.updateMany
  • Model.updateOne
  • Query.prototype.find
  • Query.prototype.findOne
  • Query.prototype.findOneAndDelete
  • Query.prototype.findOneAndUpdate
  • Query.prototype.findOneAndRemove
  • Query.prototype.findOneAndReplace
  • Query.prototype.validate
  • Query.prototype.deleteOne
  • Query.prototype.deleteMany
  • Query.prototype.exec
  • QueryCursor.prototype.close
  • QueryCursor.prototype.next

Если вы используете вышеперечисленные функции с обратными вызовами, рекомендуется перейти к async/await или обещаниям, если асинхронные функции вам не подходят. Если вам нужна помощь в рефакторинге старого кода, воспользуйтесь этим инструментом от Mastering JS по преобразованию обратных вызовов в async await с помощью ChatGPT.

// Before
conn.startSession(function(err, session) {
  // ...
});

// After
const session = await conn.startSession();
// Or:
conn.startSession().then(sesson => { /* ... */ });

// With error handling
try {
  await conn.startSession();
} catch (err) { /* ... */ }
// Or:
const [err, session] = await conn.startSession().then(
  session => ([null, session]),
  err => ([err, null])
);

Удален update()

Model.update(), Query.prototype.update(), и Document.prototype.update() были удалены. Используйте updateOne() вместо этого.

// Before
await Model.update(filter, update);
await doc.update(update);

// After
await Model.updateOne(filter, update);
await doc.updateOne(update);

Схемы дискриминатора по умолчанию используют опции базовой схемы

При использовании Model.discriminator(), Mongoose теперь по умолчанию будет использовать опции базовой схемы дискриминатора. Это означает, что вам не нужно явно устанавливать опции схемы дочерних объектов, чтобы они соответствовали базовой схеме.

const baseSchema = Schema({}, { typeKey: '$type' });
const Base = db.model('Base', baseSchema);

// In Mongoose 6.x, the `Base.discriminator()` call would throw because
// no `typeKey` option. In Mongoose 7, Mongoose uses the base schema's
// `typeKey` by default.
const childSchema = new Schema({}, {});
const Test = Base.discriminator('Child', childSchema);

Test.schema.options.typeKey; // '$type'

Удален castForQueryWrapper, обновлена сигнатура castForQuery()

Mongoose теперь всегда вызывает метод SchemaType castForQuery() с 3 аргументами: $conditional, value, и context. Если вы реализовали пользовательский тип схемы, который определяет свой собственный метод castForQuery(), вам необходимо обновить метод следующим образом.

// Mongoose 6.x format:
MySchemaType.prototype.castForQuery = function($conditional, value) {
  if (arguments.length === 2) {
    // Handle casting value with `$conditional` - $eq, $in, $not, etc.
  } else {
    value = $conditional;
    // Handle casting `value` with no conditional
  }
};

// Mongoose 7.x format
MySchemaType.prototype.castForQuery = function($conditional, value, context) {
  if ($conditional != null) {
    // Handle casting value with `$conditional` - $eq, $in, $not, etc.
  } else {
    // Handle casting `value` with no conditional
  }
};

Копирование опций схемы в Schema.prototype.add()

Mongoose теперь копирует пользовательские опции схемы при добавлении одной схемы к другой. Например, childSchema ниже получит опции baseSchema id и toJSON.

const baseSchema = new Schema({ created: Date }, { id: true, toJSON: { virtuals: true } });
const childSchema = new Schema([baseSchema, { name: String }]);

childSchema.options.toJSON; // { virtuals: true } in Mongoose 7. undefined in Mongoose 6.

Это применяется как при создании новой схемы с использованием массива схем, так и при вызове add() следующим образом.

childSchema.add(new Schema({}, { toObject: { virtuals: true } }));

childSchema.options.toObject; // { virtuals: true } in Mongoose 7. undefined in Mongoose 6.

ObjectId bsontype теперь имеет строчную букву d

Внутреннее свойство _bsontype в ObjectIds равно 'ObjectId' в Mongoose 7, в отличие от 'ObjectID' в Mongoose 6.

const oid = new mongoose.Types.ObjectId();

oid._bsontype; // 'ObjectId' in Mongoose 7, 'ObjectID' in older versions of Mongoose

Пожалуйста, обновите все места, где вы используете _bsontype для проверки, является ли объект ObjectId. Это также может повлиять на библиотеки, использующие Mongoose.

Удалена mapReduce

MongoDB больше не поддерживает mapReduce, поэтому в Mongoose 7 отсутствует функция Model.mapReduce(). Используйте фреймворк агрегации в качестве замены для mapReduce().

// The following no longer works in Mongoose 7.
const o = {
  map: function() {
    emit(this.author, 1);
  },
  reduce: function(k, vals) {
    return vals.length;
  }
};

await MR.mapReduce(o);

Удалена поддержка пользовательских библиотек обещаний

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

const mongoose = require('mongoose');

// No-op on Mongoose 7
mongoose.Promise = require('bluebird');

Если вы хотите использовать Bluebird для всех обещаний глобально, выполните следующие действия:

global.Promise = require('bluebird');

Изменения, специфичные для TypeScript

Удален LeanDocument и поддержка extends Document

Mongoose 7 больше не экспортирует тип LeanDocument и больше не поддерживает передачу типа документа, который extends Document в Model<>.

// No longer supported
interface ITest extends Document {
  name?: string;
}
const Test = model<ITest>('Test', schema);

// Do this instead, no `extends Document`
interface ITest {
  name?: string;
}
const Test = model<ITest>('Test', schema);

// If you need to access the hydrated document type, use the following code
type TestDocument = ReturnType<(typeof Test)['hydrate']>;

Новые параметры для HydratedDocument

Тип HydratedDocument Mongoose преобразует интерфейс сырого документа в тип гидратированного документа Mongoose, включая виртуальные свойства, методы и т. д. В Mongoose 7 параметры обобщения для HydratedDocument изменились. В Mongoose 6 параметры обобщения были:

type HydratedDocument<
  DocType,
  TMethodsAndOverrides = {},
  TVirtuals = {}
> = Document<unknown, any, DocType> &
Require_id<DocType> &
TMethodsAndOverrides &
TVirtuals;

В Mongoose 7 новый тип выглядит следующим образом.

type HydratedDocument<
  DocType,
  TOverrides = {},
  TQueryHelpers = {}
> = Document<unknown, TQueryHelpers, DocType> &
Require_id<DocType> &
TOverrides;

В Mongoose 7 первый параметр — это интерфейс сырого документа, второй — любые настраиваемые параметры, относящиеся к документу (обычно виртуальные свойства и методы), а третий — любые вспомогательные функции запроса, связанные с моделью документа.

Ключевое различие заключается в том, что в Mongoose 6 третьим параметром обобщения были виртуальные свойства документа. В Mongoose 7 третьим параметром обобщения являются вспомогательные функции запроса документа.

// Mongoose 6 version:
type UserDocument = HydratedDocument<TUser, TUserMethods, TUserVirtuals>;

// Mongoose 7:
type UserDocument = HydratedDocument<TUser, TUserMethods & TUserVirtuals, TUserQueryHelpers>;

© 2010 LearnBoost
Licensed under the MIT License.
https://mongoosejs.com/docs/migrating_to_7.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API