How do i join user with company that are primary to the user? see below for sample the data.
db.companies.insert([
{ "_id" : 4, "name" : "CompanyABC"},
{ "_id" : 5, "name" : "CompanyLMN"},
{ "_id" : 6, "name" : "CompanyXYZ"},
])
db.user.insert([
{
"_id": 1,
"name": "john",
"companies": [
{
"_id": 4,
"primary": true
},
{
"_id": 5,
"primary": false
},
{
"_id": 6,
"primary": false
}
]
},
"_id": 2,
"name": "jane",
"companies": [
{
"_id": 4,
"primary": false
},
{
"_id": 5,
"primary": true
},
{
"_id": 6,
"primary": false
}
]
},
])
I tried doing this below but it returned empty.
db.users.aggregate( [{
'$lookup' => [
'from' => 'companies',
'let' => ['company' => '$companies'],
'pipeline' => [
[
'$match' => [
'$expr' => [
'$and' => [
['$eq' => ['$_id', '$$company._id']],
['$eq' => ['$$company.primary', true]]
]
]
]
]
],
'as' => 'actualCompanies',
]
}]
steevej
(Steeve Juneau)
June 16, 2022, 6:06pm
2
Can a user have more that one primary?
I would do that in 2 stages:
a $set stage that $reduce the user’s companies to the primary
do a normal $lookup using the field created in the $set stage above as localField
Should be easier to debug since you can stop after stage 1 and see if the $set field works correctly. Then it is a trivial $lookup.
1 Like
MaBeuLux88
(Maxime Beugnet)
June 16, 2022, 7:16pm
3
To keep things simple, I would do it like that.
[
{
'$addFields': {
'companies': {
'$filter': {
'input': '$companies',
'as': 'item',
'cond': {
'$eq': [
'$$item.primary', true
]
}
}
}
}
}, {
'$lookup': {
'from': 'companies',
'localField': 'companies._id',
'foreignField': '_id',
'as': 'companies'
}
}
]
There is probably a way to make it work with the subpipeline like you tried, but apparently I’m not good enough just yet.
The array isn’t helping.
Cheers,
Maxime.
2 Likes
thanks Steevej, got the idea now. its pretty much like what MaBeuLux88 suggested below.
Didn’t think that way initially, it’s probably just that im still having the MySQL way of doing things right now though. =) The debugging by stage will really be handy idea for me going forward.
2 Likes
@ MaBeuLux88 Thanks, this is how i ended up using.
1 Like
Just before i close this topic, let me clarify that the solution i initially tried is actually legit and would work, i just messed up the ‘$expr’ part. see below for the corrected code:
'$expr' => [
'$and' => [
['$eq' => ['$companies._id', '$company._id']],
['$eq' => ['$companies.primary', true]]
]
]
I just replaced the ‘$_id’ with ‘$companies’ then the ‘$$company.primary’ with ‘$companies.primary’. I was just confused and forgot that i was joining companies to users, not users to company. see full code corrected code below:
db.users.aggregate( [{
'$lookup' => [
'from' => 'companies',
'let' => ['company' => '$companies'],
'pipeline' => [
[
'$match' => [
'$expr' => [
'$and' => [
['$eq' => ['$companies._id', '$$company._id']],
['$eq' => ['$companies.primary', true]]
]
]
]
]
],
'as' => 'actualCompanies',
]
}]
But moving forward i’d probably be using the staged method as suggested by @steevej . Thanks for the replies…
1 Like
MaBeuLux88
(Maxime Beugnet)
June 17, 2022, 2:19am
7
I got the same confusion when I tried! I’m glad you got it to work.
1 Like
system
(system)
Closed
June 22, 2022, 2:19am
8
This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.