Проблемы с поиском и соответствием множественным коллекциям - PullRequest
1 голос
/ 23 января 2020

Проблемы с агрегатом и поиском в несколько этапов. Проблема в том, что я не могу сопоставить userId в последнем поиске. Если я опускаю { $eq: ['$userId', '$$userId'] }, это работает и соответствует другим критериям. Но не по userid.

Я пробовал добавлять пулы в качестве разрешения и использовать его как { $eq: ['$userId', '$$pools.userId'] } на последнем этапе, но это тоже не работает. Я получаю пустой массив купонов.

Я получаю это с помощью запроса ниже. Я думаю, что мне нужно каким-то образом использовать $unwind? Но пока это не работает. Есть какие-нибудь указатели?

Всего нужно объединить три коллекции. Сначала userModel должен содержать пулы, а затем пулы должны содержать купоны пользователей.

{
   "userId": "5df344a1372f345308dac12a", // Match this usedId with below userId coming from the coupon

   "pools": [
               {
                "_id": "5e1ebbc6cffd4b042fc081ab",
                "eventId": "id999",
                "eventStartTime": "some date",
                "trackName": "tracky",
                "type": "foo bar",
                "coupon": []
               }
            ]
  },

Мне нужно, чтобы массив купонов был заполнен правильными данными (ниже), в которых есть соответствующий идентификатор пользователя.

"coupon": [
                {
                    "eventId": "id999",
                    "userId": "5df344a1372f345308dac12a",  // This userId need to match the above one
                    "checked": true,
                    "pool": "a pool",
        }           

poolProject:

const poolProject = {
    eventId: 1,
    eventStartTime: 1,
    trackName: 1,
    type: 1,
  };

Userproject:

const userProjection = {
    _id: {
      $toString: '$_id',
    },
    paper: 1,
    correctBetsLastWeek: 1,
    correctBetsTotal: 1,
    totalScore: 1,
    role: 1,
  };

Совокупный запрос

  const result = await userModel.aggregate([
{ $project: userProjection },
{
  $match: {
    $or: [{ role: 'User' },
      { role: 'SuperUser' }],
  },
},
{ $addFields: { userId: { $toString: '$_id' } } },
{
  $lookup: {
    from: 'pools',
    as: 'pools',
    let: { eventId: '$eventId' },
    pipeline: [
      { $project: poolProject },
      {
        $match: {
          $expr: {
            $in: ['$eventId', eventIds],
          },
        },
      },
      {
        $lookup: {
          from: 'coupons',
          as: 'coupon',
          let: { innerUserId: '$$userId' },
          pipeline: [
            {
              $match: {
                $expr: {
                  $eq: ['$userId', '$$innerUserId'],
                },
              },
            },
          ],
        },
      },
    ],
  },
},
]);

Спасибо за любой ввод!

Редактировать: Если я перемещаю второй поиск (купон), чтобы они были на том же «уровне», это работает, но я хотел бы иметь его внутри пула. Если я добавлю as: 'pools.coupon', в последнем поиске он перезапишет данные поискового пула.

1 Ответ

1 голос
/ 23 января 2020

Когда вы обращаетесь к полям с префиксом $$, это означает, что они определяются как «специальные» системные переменные с помощью Mon go.

Мы не знаем точно, как Mon go волхвы c происходит, но вы называете две переменные с одинаковым именем, что вызывает конфликт, как кажется.

Так что либо удалите userId: '$userId' из первого поиска, поскольку вы даже не используете его.

Или переименуйте или введите userId: '$userId' другое имя, например innerUserId: '$userId', чтобы избежать конфликтов при доступе к нему.

Просто не забудьте изменить { $eq: ['$userId', '$$userId'] } на { $eq: ['$userId', '$$innerUserId'] } после.

РЕДАКТИРОВАТЬ:

Теперь, когда его очистить нет поля userId в pools коллекции просто измените переменную во второй коллекции lookup с:

let: { innerUserId: '$userId' } //userId does not exist in pools.

На:

let: { innerUserId: '$$userId' }
...