Как правильно сделать облако тегов с MongoDB?

Кейс примерно следующий:

1. Есть n пользователей, каждый может размещать документы
2. К каждому посту пользователь может добавлять теги
3. Пользователи между собой не пересекаются, работают каждый со своими документами

Документ (без лишних полей):
{
  userId: ObjectId('...'),
  tags: ['foo', 'bar', 'baz']
}


4. Пользователь заходит на страницу со списком своих документов. Допустим выводятся первые 10, а у него их 100, есть пагинатор.
5. На этой же страницы выводится облако тегов со всеми тегами (или фильтр постов по тегам), без дублей. То есть, если бы у нас было два документа, один с тегами 'foo' и 'bar', второй - с тегами 'bar' и 'baz', то вывелось бы 'foo, bar, baz'.

Какие я вижу варианты:

1. Можно доставать из базы все документы, собирать массив тегов и выкидывать из него дубли. Возможно стоит кэшировать результат такой выборки (куда?).

2. Можно не сохранять теги в документ, а хранить их в отдельной коллекции
{
  userId: ObjectId('...'),
  tags: [ObjectId('...'), ObjectId('...')]
}

Но это ведь уже MySQL получится.

Как решить такую задачу правильно?
  • Вопрос задан
  • 306 просмотров
Решения вопроса 1
Ptolemy_master
@Ptolemy_master
Я бы сделала так.
Страница со списком документов загружается как обычно, попутно подгружается список тэгов, который хранится как обычный массив строк, привязанный к профилю пользователя, сформированный как описано в вашем варианте номер 1. (Делать отдельную коллекцию для простых списков смысла не вижу, всегда лучше начинать с минимизации сущностей - бритва Оккама, ага :)
Когда мы загружаем страницу со списком, идет подгрузка тэгов. Все последующие обращения к другим страницам делаются асинхронно, следовательно, облако тэгов больше загружать не надо.
Я не знаю, что вы используете на клиенте, я работаю плотно с Angular, поэтому говорить могу только про него.
Технически это было бы сделано так - маршрут для списка документов прописан на сервере, идет возврат клиенту профиля со списком тэгов. А маршруты ангуляра содержат обращения к страницам. В случае первичной загрузки идет запрос на страницу номер 1 (как resolver для этого маршрута), последующие вызовы - просто асинхронно к выборке соответствующей страницы.

Добавление.
Автор поста задал дополнительный вопрос. Вы спрашивали, когда обновлять список. Вопрос не такой просто и очевидный. В идеальном варианте облако тэгов должно обновляться сразу же как только пользователь добавил или изменил существующие тэги. Если хотите реализовать именно эту функциональность, то можно сделать через сокеты (новый список тэгов посылается клиенту в браузер, это не сложно на самом деле). Другой вариант - отслеживать на сервере при сохранении документа, изменился ли список тэгов, и, если да, в ответе отправлять обновленный список и его на клиенте обновлять. Тоже ничего вариант, по-моему.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@AnneSmith
самая ленивая
я до монго еще как-то не добралась, но с json работала достаточно, я бы не делала отдельную коллекцию тэгов, потому что пользователи не пересекаются

погуглите "merge arrays remove duplicates" для вашего языка программирования
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы