Как правильно иметь отношение один-к-одному в MongoDB без каких-либо минусов? - PullRequest
0 голосов
/ 16 января 2019

Я работаю над проектом, и у меня есть эти две коллекции MongoDB: команда (содержит данные о командах) и оплата (содержит оплату команд) (строго 1-1 отношения).

Payment Schema
{
    ...
    team: { type: Schema.Types.ObjectId, ref: 'Team', unique: true },
    ...
}

Для команды у меня есть две альтернативы:

Team1 Schema
{
    user_id: { type: Schema.Types.ObjectId, ref: 'User' }
}

...

Team2 Schema
{
    user_id: { type: Schema.Types.ObjectId, ref: 'User' }
    payment: { type: Schema.Types.ObjectId, ref: 'Payment', unique: true }
}

NEED: У меня есть компонент "Мои команды", где мне нужнопоказать вошедшего в систему пользователя все команды и его статус платежа (да / нет).

ВЫПУСК С Team1 Схема: Поскольку у меня нет ссылки на Платеж, поэтому мне нужно сделать еще один звонокбэкэнд с _id команды, чтобы получить объект оплаты для каждой команды.Если у пользователя есть 10 команд, то это будут 11 внутренних вызовов (1 для команд, следующие 10 для их статусов платежей).

ВЫПУСК С Схемой Team2: Поскольку у меня теперь есть Payment _id внутриСхема Team2, поэтому я могу просто проверить, существует ли это поле или нет, чтобы определить, оплачено ли оно или нет.Но теперь проблема в том, что при совершении платежа мне нужно обновить обе коллекции и использовать транзакции (для отката в случае сбоя), что увеличивает сложность и также не поддерживается, если у меня не установлен набор реплик.

Не могли бы вы помочь мне выяснить это как можно лучше?

Заранее спасибо.

1 Ответ

0 голосов
/ 16 января 2019

Самое простое решение - просто указать team_id в схеме платежей (которая у вас уже есть).

Вам не нужны ни user_id, ни payment_id в схеме команды, чтобы получать платежи с командой. Вы можете просто получить сводный запрос с поиском в таблице платежей, чтобы получить команду вместе с оплатой.

Итак, учитывая, что у вас есть ID команд и вам нужны данные о командах вместе с данными о платежах, вы можете написать запрос агрегации, что-то вроде этого,

             Team.aggregate([
            {
                $match: { _id: { $in: list_of_user_ids } } // this will get the teams which match the array of ids
            },
            {
                $lookup: // this will search data from a different collection
                {
                    from: 'payments', // the collection to search from
                    localField: '_id', // the matching field in the team collection
                    foreignField: 'team', // matching field in the payment colection
                    as: 'payment' the name you want to give to the resulting payment object
                }
            }
           ])

Редактировать 1: Поиск, который я написал, делает именно то, что вам нужно. Просто я предположил, что у вас есть массив идентификаторов пользователей. Если у вас один идентификатор пользователя, просто измените операцию сопоставления на то, что вы написали

           $match: { user_id:  currently_loggedin_userId } 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...