Spec-Zone.ru › Mongoose

Дискриминаторы

Функция model.discriminator()

Дискриминаторы — это механизм наследования схем. Они позволяют иметь несколько моделей с перекрывающимися схемами поверх одной и той же базовой коллекции MongoDB.

Предположим, вам нужно отслеживать различные типы событий в одной коллекции. Каждое событие будет иметь отметку времени, но события, представляющие нажатия на ссылки, должны иметь URL. Вы можете добиться этого, используя функцию model.discriminator(). Эта функция принимает 3 параметра: имя модели, схему дискриминатора и необязательный ключ (по умолчанию — имя модели). Она возвращает модель, схема которой является объединением базовой схемы и схемы дискриминатора.

const options = { discriminatorKey: 'kind' };

const eventSchema = new mongoose.Schema({ time: Date }, options);
const Event = mongoose.model('Event', eventSchema);

// ClickedLinkEvent is a special type of Event that has
// a URL.
const ClickedLinkEvent = Event.discriminator('ClickedLink',
  new mongoose.Schema({ url: String }, options));

// When you create a generic event, it can't have a URL field...
const genericEvent = new Event({ time: Date.now(), url: 'google.com' });
assert.ok(!genericEvent.url);

// But a ClickedLinkEvent can
const clickedEvent = new ClickedLinkEvent({ time: Date.now(), url: 'google.com' });
assert.ok(clickedEvent.url);

Дискриминаторы сохраняются в коллекцию модели "Событие"

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

const event1 = new Event({ time: Date.now() });
const event2 = new ClickedLinkEvent({ time: Date.now(), url: 'google.com' });
const event3 = new SignedUpEvent({ time: Date.now(), user: 'testuser' });


await Promise.all([event1.save(), event2.save(), event3.save()]);
const count = await Event.countDocuments();
assert.equal(count, 3);

Ключи дискриминатора

Способ, которым Mongoose различает различные модели дискриминаторов, — это «ключ дискриминатора», который по умолчанию __t. Mongoose добавляет строковый путь, называемый __t, к вашим схемам, который используется для отслеживания, экземпляром какого дискриминатора является данный документ.

const event1 = new Event({ time: Date.now() });
const event2 = new ClickedLinkEvent({ time: Date.now(), url: 'google.com' });
const event3 = new SignedUpEvent({ time: Date.now(), user: 'testuser' });

assert.ok(!event1.__t);
assert.equal(event2.__t, 'ClickedLink');
assert.equal(event3.__t, 'SignedUp');

Изменение ключа дискриминатора

По умолчанию Mongoose не позволяет изменять ключ дискриминатора. save() будет выводить ошибку, если вы попытаетесь изменить ключ дискриминатора. А findOneAndUpdate(), updateOne(), и т. д. будут игнорировать изменения ключа дискриминатора.

let event = new ClickedLinkEvent({ time: Date.now(), url: 'google.com' });
await event.save();

event.__t = 'SignedUp';
// ValidationError: ClickedLink validation failed: __t: Cast to String failed for value "SignedUp" (type string) at path "__t"
  await event.save();

event = await ClickedLinkEvent.findByIdAndUpdate(event._id, { __t: 'SignedUp' }, { new: true });
event.__t; // 'ClickedLink', update was a no-op

Чтобы изменить ключ дискриминатора документа, используйте findOneAndUpdate() или updateOne() с опцией overwriteDiscriminatorKey установленной следующим образом.

let event = new ClickedLinkEvent({ time: Date.now(), url: 'google.com' });
await event.save();

event = await ClickedLinkEvent.findByIdAndUpdate(
  event._id,
  { __t: 'SignedUp' },
  { overwriteDiscriminatorKey: true, new: true }
);
event.__t; // 'SignedUp', updated discriminator key

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

Spec-Zone.ru

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