Я хотел бы обсудить с вами, если имеет смысл использовать двухстороннее встраивание вместо одностороннего встраивания при моделировании отношения N: M в MongoDB.
Скажем, у нас есть два объекта : A Продукт может принадлежать многим (нескольким) категориям , а Категория может иметь много (много) продуктов .
Двустороннее вложение
Если мы используем этот подход, наши категории будут выглядеть так:
{
_id: 1,
name: "Baby",
products: [2]
}
{
_id: 2,
name: "Electronics",
products: [1, 2]
}
И продукты :
{
_id: 1,
name: "HDMI Cable",
categories: [2]
}
{
_id: 2,
name: "Babyphone",
categories: [1, 2]
}
Запросы:
Если мы хотим получить продукты, принадлежащие к определенной категории c:
const category = categoriesCollection.findOne({name: "Electronics"});
const products = productsCollection.find({_id: {$in: category.products}}).toArray();
Если мы хотим получить категории принадлежащие указанному c продукту:
const product = productsCollection.findOne({name: "Babyphone"});
const categories = categoriesCollection.find({_id: {$in: product.categories}}).toArray();
Вложение в один конец
Поскольку продукт, вероятно, будет принадлежать только двум или трем категориям, но категория может иметь миллионы продуктов, Я бы встраивал категории в продукты, а не наоборот. Таким образом, мы можем быть уверены, что никогда не достигнем максимального размера документа 16 МБ.
Наши продукты будут выглядеть так же, как и выше, но категории больше не будут иметь поля "продукты".
Если мы хотим получить категории для определенного продукта c, наш запрос остается таким же, как указано выше:
const product = productsCollection.findOne({name: "Babyphone"});
const categories = categoriesCollection.find({_id: {$in: product.categories}}).toArray();
И наоборот, если мы выбираем продукты для указанного c category, наш запрос изменяется следующим образом:
const category = categoriesCollection.findOne({name: "Electronics"});
const products = productsCollection.find({categories: category._id}).toArray();
В нашей коллекции продуктов мы помещаем (multikey) index в массив категорий, поэтому производительность должна быть в порядке.
Мой вывод
Одностороннее встраивание кажется мне лучшим решением, поскольку мы не достигнем максимального размера документа, не имея при этом никаких (?) Недостатков в отношении способ встраивания. Зачем кому-то хотеть делать двустороннее встраивание? Я что-то пропустил? Что касается производительности, она должна быть почти такой же или нет?
Как вы думаете?