Добавьте два дополнительных фильтра из 1 коллекции, используя Монго - PullRequest
0 голосов
/ 24 мая 2018

У меня есть 4 коллекции:

пользователи

users: { id: '123123123', name: 'MrMins' }

совпадения

{ id: 1, team1: 23, team2: 24, date: '6/14', matchday: 1, locked: false, score1: null, score2: null }
{ id: 2, team1: 9, team2: 32, date: '6/15', matchday: 1, locked: false, score1: null, score2: null }

страны

{id: 23, country: "Russia", pais: "Rusia", group: 'A' }
{id: 24, country: "Saudi Arabia", pais: "Arabia Saudita", group: 'A' }
{id: 9, country: "Egypt", pais: "Egipto", group: 'A' }
{id: 32, country: "Uruguay", pais: "Uruguay", group: 'A' }

прогноз

{ matchid: 1, score1: 3, score2: 4, userid: '123123123' }
{ matchid: 2, score1: 3, score2: 0, userid: '123123123' }

Мой запрос:

db.collection('matches').aggregate([
    {
        $lookup: {
          from: 'countries',
          localField: 'team1',
          foreignField: 'id',
          as: 'team1'
        }
    },{
        $lookup: {
          from: 'countries',
          localField: 'team2',
          foreignField: 'id',
          as: 'team2'
        }
    }
    ]).toArray(function(err, res) {
      callback(err, res);
    });

Только сейчас у меня есть соотношение между matches и countries (два раза).Как добавить дополнительный фильтр к forecast, связав его с matchid и userid?

Ответы [ 2 ]

0 голосов
/ 25 мая 2018

Это будет довольно просто при использовании версии mongodb 3.6 $lookup с использованием вложенного конвейера

db.matches.aggregate([
  {
    $lookup: {
      from: 'countries',
      let: { 'team1': '$team1' },
      pipeline: [
        { $match: { $expr: { $eq: [ '$id', '$$team1' ] } }}
      ],
      as: 'team1'
    }
  },{
    $lookup: {
      from: 'countries',
      let: { 'team2': '$team2' },
      pipeline: [
        { $match: { $expr: { $eq: [ '$id', '$$team2' ] } }}
      ],
      as: 'team2'
    }
  }, {
    $lookup: {
      from: 'forecast',
      let: { "match_id": "$id" },
      pipeline: [
        { $match: { $expr: { $eq: [ '$matchid', '$$match_id' ] } }},
        { $lookup: {
          from: 'users',
          let: { 'userid': '$userid' },
          pipeline: [
            { $match: { $expr: { $eq: [ '$id', '$$userid' ] } }}
          ],
          as: 'user'
        }}
      ],
      as: 'forecast'
    }
  }
])
0 голосов
/ 24 мая 2018

$lookup работает как левое внешнее объединение, но вставляет «объединенные» результаты в виде массива в ваш документ.Таким образом, каждое добавляемое вами поле (с использованием опции as) будет массивом.

Чтобы получить данные как из forecasts, так и users, вам нужно преобразовать этот массив в объект, и вы можете сделать это, используя $ arrayElemAt оператор:

db.matches.aggregate([
    {
        $lookup: {
          from: 'countries',
          localField: 'team1',
          foreignField: 'id',
          as: 'team1'
        }
    },{
        $lookup: {
          from: 'countries',
          localField: 'team2',
          foreignField: 'id',
          as: 'team2'
        }
    },{
        $lookup: {
          from: 'forecast',
          localField: 'id',
          foreignField: 'matchid',
          as: 'forecast'
        }
    }, {
        $addFields: {
          forecast: { $arrayElemAt: [ "$forecast", 0 ] }
        }
    },{
        $lookup: {
          from: 'users',
          localField: 'forecast.userid',
          foreignField: 'id',
          as: 'forecast.user'
        }
    }
])
...