Двухстороннее встраивание против одностороннего встраивания в MongoDB (многие ко многим) - PullRequest
1 голос
/ 24 января 2020

Я хотел бы обсудить с вами, если имеет смысл использовать двухстороннее встраивание вместо одностороннего встраивания при моделировании отношения 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 в массив категорий, поэтому производительность должна быть в порядке.

Мой вывод

Одностороннее встраивание кажется мне лучшим решением, поскольку мы не достигнем максимального размера документа, не имея при этом никаких (?) Недостатков в отношении способ встраивания. Зачем кому-то хотеть делать двустороннее встраивание? Я что-то пропустил? Что касается производительности, она должна быть почти такой же или нет?

Как вы думаете?

...