使用mongo添加两个额外的1个集合过滤器

时间:2018-05-24 19:19:08

标签: mongodb mongodb-query node-mongodb-native

我有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);
    });

刚才我有matchescountries之间的关系(两次)。 我如何添加额外的过滤条件forecastmatchiduserid建立关系?

2 个答案:

答案 0 :(得分:1)

使用 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'
    }
  }
])

答案 1 :(得分:0)

$lookup用作左外连接,但它插入"已加入"结果作为文档中的数组。因此,您添加的每个字段(使用as选项)都将是一个数组。

要从forecastsusers获取数据,您必须将该数组转换为对象,然后使用$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'
        }
    }
])