Я создаю приложение, которое использует классический механизм "follow" (тот, который используется Twitter и множество других приложений в Интернете). Я использую MongoDB. Однако у моей системы есть разница: пользователь может следить за группами пользователей. Это означает, что если вы будете следовать за группой, вы автоматически будете следовать за всеми пользователями, входящими в эту группу. Конечно, пользователи могут принадлежать более чем одной группе.
Вот что я придумал:
- когда пользователь A следует пользователю B, идентификатор пользователя B добавляется во встроенный массив (называемый
following
) в документе пользователя A - для unfollowing, я удаляю идентификатор следующего пользователя из массива
following
Группы -
работают одинаково: когда пользователь A следует группе X, идентификатор группы X добавляется в массив
following
. (Я фактически добавляюDBRef
, поэтому я знаю, связано ли соединение с пользователем или группой.) -
когда мне нужно проверить, следует ли пользователь A группа X, я просто ищу идентификатор группы пользователя A массив.
- когда мне нужно проверить, соответствует ли пользователь A пользователю B, все становится немного сложнее. Каждый пользовательский документ имеет встроенный массив, в котором перечислены все группы, к которым принадлежит пользователь. Поэтому я использую условие
$or
для проверки того, является ли пользователь A либо непосредственно пользователем пользователя B, либо через группу. Как это:db.users.find({'$or':{'following.ref.$id':$user_id,'following.ref.$ref','users'},{'following.ref.$id':{'$in':$group_ids},'following.ref.$ref':'groups'}}})
Это отлично работает, но я думаю, что у меня есть несколько вопросов. Например, как показать список подписчиков для конкретного пользователя, включая разбиение на страницы? Я не могу использовать skip() и limit() во встроенном документе.
Я мог бы изменить дизайн и использовать коллекцию userfollow
, которая выполнила бы ту же работу встроенного документа following
. Проблема с этим подходом, который я пробовал, заключается в том, что с условием $or
, которое я использовал ранее, пользователи, следующие за двумя группами, содержащими один и тот же пользователь, будут перечислены дважды. Чтобы этого избежать, я мог бы использовать группу или MapReduce, которые я действительно делал, и это работает, но я бы хотел избежать этого, чтобы упростить ситуацию. Может быть, мне просто нужно думать из коробки. Или, возможно, я предпринял неправильный подход с обеих попыток. Кто-то уже должен был сделать подобную вещь и придумал лучшее решение?
(На самом деле это следующий вопрос этого старого вопроса. Я решил опубликовать новый вопрос, чтобы лучше объяснить мою новую ситуацию, надеюсь, что это не проблема.)