Проблема:
Я пытаюсь получить список документов и для каждого из них рассчитать количество вхождений данного значения в один и тот же вложенный массивdocument.
У меня есть рабочий пример использования структуры агрегации, но мне интересно, есть ли лучший способ сделать то же самое, поэтому я могу сравнить различные подходы.
Упрощенная модель данных:
Отдельный документ в сборнике "Raffles":
{
"_id" : objectId,
"name" : string,
"ends_at" : ISODate/Timestamp,
...
"subscribers" : string[] //List of user ids
}
- Коллекциисостоит из документов, представляющих лотерею / лотерею с названием и датами начала / окончания.
- Пользователи могут подписаться на лотерею.
- Пользователи могут подписаться несколько раз на одну и ту же лотерею.
95% запросов на чтение потребуют как данные лотереи, такие как имя, описание и даты + информация о подписанных пользователях.Вот почему я решил хранить все в одном лотерейном документе вместо: ссылки на подписанные лотереи в пользовательском документе или отдельную коллекцию с лотереями и количеством подписок.
Альтернатива может быть?:
Массив subscribers
представляет собой список строк, представляющих идентификатор пользователя.Таким образом, добавить подписчика так же просто, как нажать новое значение.Другой вариант - создать массив объектов, подобных этому, и увеличить счетчик:
{
"subscribers: [
{
"id": objectId //User id
"count": integer //Number of subscriptions
},
...
]
}
Ожидаемый результат:
Ожидаемый результат - полная лотереяdocument + дополнительное значение количества подписок данного пользователя.
{
"_id" : objectId,
"name" : string,
"ends_at" : ISODate/Timestamp,
...
"subscriptions" : 3 //Number of entries for a given user
}
Текущее решение
Я получаю размер после фильтрации вложенного массива с помощьюзаданный идентификатор пользователя
db.raffles.aggregate([
...
{
$project: {
"name" : 1,
"ends_at" :1,
...
"subscriptions" : {
$size : {
$filter : {
input: "$subscribers",
as: "user",
cond: {
$eq: ["$$user", <USER_ID>]
},
}
}
}
}
}
...
])
Вопросы:
Существуют ли другие / более эффективные способы достижения результата из текущего решения?Может быть, группировать и суммировать или отображать / уменьшать?
Стоит ли хранить не только идентификаторы пользователей, но и объекты с идентификатором пользователя и количеством подписок?
Текущее решение выдаст ошибку, если массив subscriptions
не установлен.Есть ли способ справиться с этим?
Большое спасибо за потраченное время на чтение этого длинного поста!