#node.js #mongodb #inheritance
Вопрос:
У нас есть модель контента, в которой мы устанавливаем контент на центральном уровне, но пользователи имеют возможность редактировать контент до вспомогательного уровня, если захотят. Если они не хотят ничего менять по сравнению с тем, что устанавливается из центра, им это не нужно.
Давайте предположим, что простая конечная точка api, которая просто принимает идентификатор компании. Вот как он отреагировал бы:
GET /offers (central values)
[{
offerId: 1,
title: "Central offer title",
paragraph: "Lorem ipsum central",
price: 100
}, {...more offers}]
Компания 123
/offers?companyId=123
[{
offerId: 1,
title: "Company offer title",
paragraph: "Lorem ipsum central", // Inherited from central
price: 125
}, {...more offers}]
Компания 456, которая является дочерней компанией 123
/offers?companyId=456
[{
offerId: 1,
title: "Company offer title", // Inherited from Company 1
paragraph: "Lorem ipsum subsidiary",
price: 125, // Inherited from Company 1
custom_field: "A completely custom field for subsidiary" // Field only available for subsidiary
}, {...more offers}]
В предыдущих реализациях мы делали что-то в духе:
{
offerId: 1,
values: [
{
companyId: null,
title: "Central offer title",
paragraph: "Lorem ipsum central",
price: 100
},
{
companyId: 123,
title: "Company offer title",
price: 125
},
{
companyId: 456,
paragraph: "Lorem ipsum subsidiary",
custom_field: "A completely custom field for subsidiary"
}
]
}
А затем в приложении мы скомпилировали это так, чтобы значения были специфичны для дочерней компании, но все равно наследовали данные от центральной или материнской компании.
Теперь, когда мы собираемся написать новые приложения, которые должны снова разрешить наследование контента такого типа, у нас возникают сомнения по поводу этого подхода и мы задаемся вопросом, есть ли другой способ смоделировать это.
Какие еще существуют способы моделирования такого типа поведения?
Ответ №1:
Вы используете мангуста? Если да — используйте дискриминаторы:
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' });
Подробнее на эту тему в этой статье читайте: https://dev.to/helenasometimes/getting-started-with-mongoose-discriminators-in-expressjs—22m9
Если нет — тогда, я думаю, вам следует придерживаться того же подхода, что и в мангусте, — иметь каждую компанию в виде отдельного документа. Потому что в вашей старой настройке есть несколько вещей:
- Компания находится в документе предложения
- Если в нескольких предложениях используются одни и те же компании, вы бы дублировали данные компании, верно?
- Нет простого способа найти компанию — вы получаете предложения.ценности и ищете недвижимость внутри. Это в основном обход всей вашей базы данных.
Если вы выполняете поиск только по компании (а не предлагаете идентификатор, как вы сказали), вы можете отменить их. Но все равно это странно. Я бы разделил их на две отдельные части и использовал ссылки между ними. Таким образом, вы могли бы:
- Найдите компанию по идентификатору
- Найдите его родителя (делайте это до тех пор, пока родителя не будет; используйте aggregate, чтобы сделать это в одном запросе)
- Получите список предложений для этой компании (свойство документа) и запросите их
Такой подход позволил бы вам сделать обратное (предложить компании).
Комментарии:
1. В старой настройке есть тысячи предложений, а также сотни компаний. Сущность компании отделена от этих данных, мы просто используем идентификационный номер. Я думаю, что Дискриминаторы решают проблему, отличную от той, с которой я сталкиваюсь. Мне кажется, что дискриминаторы просто наследуют схему, но в моем случае я хочу унаследовать как схему, так и ее значения.
2. Уточнил сообщение, чтобы показать, что это может быть несколько предложений