Как моделировать отношения «многие ко многим» в MongoDB (для пользователя MySQL) - PullRequest
9 голосов
/ 30 ноября 2011

Я родом из MySQL фона и пытаюсь обернуть голову вокруг MongoDB. В частности, я изо всех сил пытаюсь осмыслить, как я должен смоделировать n:n отношения "по Монго".

Для этого примера, скажем, у нас есть два collections: users и interests. Нам нужно иметь возможность представлять или запрашивать несколько данных в наших данных:

  • Интересы пользователя
  • Пользовательский рейтинг интереса, например, "нравится" или "не нравится"
  • Пользователи с данным интересом
  • Счетчик (который может быть увеличен / уменьшен) каждого рейтинга интереса
  • Название интереса

В MySQL я бы создал таблицу users_interests, индексированную для обоих идентификаторов пользователей и идентификаторов процентов. Для счетчика у меня были бы отдельные столбцы для каждого типа рейтинга, и каждый раз, когда пользователь оценивал / не оценивал проценты, проводил транзакцию, чтобы гарантировать, что счетчики никогда не были ложными.

Я пытался читать о некоторых схемах , но безрезультатно.

Можете ли вы помочь потерянной душе найти путь?

Ответы [ 2 ]

11 голосов
/ 30 ноября 2011

Отличный вопрос.Позвольте мне сначала немного рассказать о том, как работает отношение N: N, а затем я подробно расскажу о каждой из ваших точек маркера.

N: N в MySQL, как правило, ваша сводная таблица связана между вашим пользователем иинтересы (таблица user_interests).В монго вы делаете это немного по-другому.У вас по-прежнему есть коллекция пользователей и интересов, однако вместо этого теперь вы храните список ключей под интересами для пользователя.ТАК что-то вроде этого:

User Collection {
      "name":"Josh",
      "user":"jsmith",
      "interests":[
           {
            "_id":12345,
            "rating":"like"
           },
           {..}..
      ]
}

Сохраняя ваши интересы в списке, который отключен на вашей таблице интересов, вы можете выполнять каждое из необходимых вам действий.Если вы хотите сделать запрос, вы бы выбрали его на основе идентификатора, который находится в таблице интересов, а затем выполните запрос, используя модификатор $ in .

Теперь для вашей коллекции интересов ясделал бы следующее:

User Interest {
      "_id":objectId
      "label":"Swimming",
      "count":intValue
}

При добавлении интереса к документу пользователя переменная count будет зависеть от определения ваших рейтингов.Если вы храните свои рейтинги в отдельной области (или в логике), то назначенное им значение будет тем, что вы соотносите с интересующим значением int.IE: пользователь оценивает его meh (который имеет значение 1), затем вы добавляете 1 к значению счета.

Надеюсь, это полезно и, по крайней мере, привело к некоторым другим идеям о том, как его структурировать.!

Удачи, помните, МОНГО УДИВИТЕЛЬНЫЙ.

1 голос
/ 30 ноября 2011

Чтобы поддерживать глобальный подсчет рейтингов каждого интереса, вам понадобится отдельная и независимая коллекция, в которой вы обновляете (добавляете или вычитаете) рейтинги с использованием атомарных операторов обновления, когда и когда действия по интересам / интересам выполняются пользователями.

Вы можете сохранить интерес каждого пользователя в виде массива вложенных документов в самой коллекции пользователя.

Структура этих данных в формате JSON будет выглядеть примерно так:

db.User
{
    name: 'joe',
    ....,
    interests : [{ name: 'swimming', rating: 10},
              { name: 'cooking', rating: 22 }
              ]
}

Теперь вы можете запрашивать внутренние ключи, используя:

> db.User.find( { "interests.name" : "cooking" } )

Это вернет пользователей, которые имеют особый интерес.

...