Как моделировать систему голосования «любит» с помощью MongoDB

В настоящее время я работаю над мобильным приложением. В основном люди могут публиковать свои фотографии, а последователям могут нравиться такие фотографии, как Instagram. Я использую mongodb в качестве базы данных. Подобно instagram, может быть много симпатий для одиночных фотографий. Поэтому использование документа для одного «похожего» с индексом кажется нецелесообразным, потому что он будет тратить много памяти. Однако я бы хотел, чтобы пользователь быстро добавил. Итак, мой вопрос заключается в том, как моделировать «как»? В основном модель данных очень похожа на instagram, но с использованием Mongodb.

Независимо от того, как вы структурируете свой общий документ, в основном вам нужны две вещи. Это, по сути, свойство четыре «счет» и «список» тех, кто уже разместил там «как», чтобы гарантировать, что дубликатов нет. Вот базовая структура:

 { "_id": ObjectId("54bb201aa3a0f26f885be2a3") "photo": "imagename.png", "likeCount": 0 "likes": [] } 

В любом случае существует уникальная «_id» для вашей «фотопостановки» и любой информации, которую вы хотите, но затем других полей, как упоминалось. Свойством «любит» здесь является массив, и он будет удерживать уникальные значения «_id» от «пользовательских» объектов в вашей системе. Таким образом, каждый «пользователь» имеет свой собственный уникальный идентификатор где-то, либо в локальном хранилище, либо в OpenId или что-то в этом роде, но в уникальном идентификаторе. Я буду придерживаться ObjectId для примера.

Когда кто-то отправляет сообщение «как» в сообщение, вы хотите выпустить следующий оператор обновления:

 db.photos.update( { "_id": ObjectId("54bb201aa3a0f26f885be2a3"), "likes": { "$ne": ObjectId("54bb2244a3a0f26f885be2a4") } }, { "$inc": { "likeCount": 1 }, "$push": { "likes": ObjectId("54bb2244a3a0f26f885be2a4") } } ) 

Теперь операция $inc будет увеличивать значение «likeCount» на указанное число, поэтому увеличится на 1. Операция $push добавляет уникальный идентификатор пользователя к массиву в документе для дальнейшего использования.

Главное здесь – сохранить запись тех пользователей, которые голосовали и что происходит в части запроса. Помимо выбора документа для обновления его собственным уникальным «_id», еще одна важная вещь – проверить, что «нравится» массив, чтобы убедиться, что текущий пользователь голосования там уже не существует.

То же самое верно для обратного случая или «удаления» «как»:

 db.photos.update( { "_id": ObjectId("54bb201aa3a0f26f885be2a3"), "likes": ObjectId("54bb2244a3a0f26f885be2a4") }, { "$inc": { "likeCount": -1 }, "$pull": { "likes": ObjectId("54bb2244a3a0f26f885be2a4") } } ) 

Главное здесь – условия запроса, используемые для обеспечения того, чтобы ни один документ не был затронут, если все условия не выполнены. Таким образом, подсчет не увеличивается, если пользователь уже голосовал или уменьшался, если их голос фактически не присутствовал на момент обновления.

Конечно, нет смысла читать массив с несколькими сотнями записей в документе обратно в любой другой части вашего приложения. Но у MongoDB есть очень стандартный способ справиться с этим:

 db.photos.find( { "_id": ObjectId("54bb201aa3a0f26f885be2a3"), }, { "photo": 1 "likeCount": 1, "likes": { "$elemMatch": { "$eq": ObjectId("54bb2244a3a0f26f885be2a4") } } } ) 

Это использование $elemMatch в проецировании будет возвращать только текущего пользователя, если они присутствуют, или просто пустой массив, где они отсутствуют. Это позволяет остальной части вашей логики приложения быть в курсе, если текущий пользователь уже поставил голосование или нет.

Это базовая техника и может работать для вас, как есть, но вы должны знать, что встроенные массивы не должны быть бесконечно расширенными, а также есть жесткий предел в 16 МБ для документов BSON. Таким образом, концепция звучит, но просто не может быть использована сама по себе, если вы ожидаете 1000 «похожих голосов» на свой контент. Существует концепция, известная как «bucketing», которая подробно обсуждается в этом примере для разработки гибридной схемы, которая позволяет одному решению хранить большой объем «симпатий». Вы можете взглянуть на это, чтобы использовать вместе с основными понятиями здесь как способ сделать это при громкости.

Interesting Posts

Избегайте автоматического подключения к беспроводной сети на окнах 7

Как определить ориентацию устройства с помощью мультимедийных запросов CSS?

Можем ли мы использовать стиль кнопки GTK + 2.0 в Java Swing?

Как я могу запланировать службу Windows C # для выполнения задачи ежедневно?

Удалять файлы из одной папки, если аналогичный файл не существует в другой папке

Стандартное значение переменной PATH Windows 10

C # JSON Сериализация словаря в {key: value, …} вместо {key: key, value: value, …}

Передача аргументов в селектор в Swift

Получить имя таблицы базы данных из Entity Framework MetaData

Как установить последнее (непомеченное) состояние репо с помощью беседки?

Как разбить большой файл на Windows?

Перенесите медиатеку iTunes * с * метаданными на новую машину

Поддерживается ли constexpr с lambda-функциями / выражениями?

Опасно ли запускать процессор в чрезвычайно холодной среде?

Правила Двигатель – за и против

Давайте будем гением компьютера.