Проверьте, присутствует ли объект в массиве, если присутствует установленное состояние true в nodejs mongoose [duplicate]

php7:

sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php7.0-fpm
sudo service apache2 restart
10
задан Neil Lunn 18 January 2015 в 04:27
поделиться

1 ответ

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

{ 
    "_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», еще одна важная вещь - проверить, что «нравится» массив, чтобы убедиться, что текущий пользователь голосования там уже отсутствует.

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

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

29
ответ дан Neil Lunn 20 August 2018 в 15:31
поделиться
  • 1
    Хороший ответ, извините за это, но что вы думаете о реализации такого решения (вместо использования вспомогательного документа для сохранения симпатий или голосов) stackoverflow.com/questions/26914380/… – Disposer 18 January 2015 в 07:19
  • 2
    @Disposer, общая идея здесь заключается в том, чтобы сделать как можно более простой способ проверить, проголосовал ли кто-то или нет, и пересчитать общий подсчет голосов без агрегации или, по крайней мере, путем разделения на как можно меньше документов. Другие модели либо полагаются на агрегацию в реальном времени, либо иначе не являются атомарными в обновлениях. Быстро писать и быстро читать. Для объектов высокой активности, которые обычно вы хотите. – Neil Lunn 18 January 2015 в 07:28
  • 3
    @Neil Lunn. Спасибо за Ваш ответ. На самом деле моя структура данных очень похожа на вашу, и я планирую использовать дизайн bucketing. Мне было интересно, насколько хороша работа по поиску большого количества ведер с помощью оператора $ elemMatch. Скажем, 300000 понравилось фотографии, у меня 300 ведер, и каждый ведро содержит 1000 понравившихся. Насколько эффективно знать, действительно ли текущий пользователь уже голосовал или нет? И меня также интересует «Другие модели либо полагаются на агрегацию в реальном времени». вы упомянули, можете ли вы объяснить больше, чтобы я мог оценить больше вариантов? – user2914635 18 January 2015 в 08:43
  • 4
    @ user2914635 То, о чем вы сейчас спрашиваете, - это действительно другой вопрос, но даже в этом он довольно широк. Если вы хотите путешествовать по различным методикам и не прочь прочесть какой-либо код, вы можете посмотреть hvdf и socialite источники. Есть даже несколько разговоров с Дареном, как этот . Также подумайте, что получение 300 000 понравившихся будет скорее исключением, чем правилом. – Neil Lunn 18 January 2015 в 08:57
  • 5
    @Neil Lunn. В принципе, дизайн рекламного дизайна заключается в том, что он экономит память и легко извлекает понравившиеся дисплеи для конечных пользователей, недостатки дизайна рекламного пакета заключаются в том, что он делает вставку более дорогой. Профессиональный подход к каждому из них, как к единому документу, заключается в том, что он делает так, что вставка как эффективно, так и для получения предпочтений также имеет разумную производительность, но она будет тратить много памяти. Правильно ли я? Как я знаю, Instagram обычно имеет много предпочтений по каждому сообщению. Предположим, у меня также много нравится для одного поста. Какую модель данных я должен взять? – user2914635 18 January 2015 в 09:06
Другие вопросы по тегам:

Похожие вопросы: