Reputation: 12034
I have 4 collections:
users
users: { id: '123123123', name: 'MrMins' }
matches
{ 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 }
countries
{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' }
forecast
{ matchid: 1, score1: 3, score2: 4, userid: '123123123' }
{ matchid: 2, score1: 3, score2: 0, userid: '123123123' }
My query:
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);
});
Just now, I have the relation between matches
, and countries
(two times).
How I can add the additional filter to forecast
doing a relation with matchid
and userid
?
Upvotes: 0
Views: 48
Reputation: 46441
It will be quite simple using the mongodb 3.6 $lookup
version with using nested pipeline
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'
}
}
])
Upvotes: 1
Reputation: 49945
$lookup
works as left outer join but it inserts "joined" results as an array in your document. So every field you add (using as
option) will be an array.
To get data both from forecasts
and users
you have to transform that array into an object and you can do it using $arrayElemAt operator:
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'
}
}
])
Upvotes: 0