Reputation: 3818
I have a join collection - and I want to pull back PEOPLE data with their Parents... How can I do this -
PEOPLE
[
{
"_id" : ObjectId("3a9ccf7de6348936d88b3601"),
"first_name" : "John",
"last_name" : "Doe"
},
{
"_id" : ObjectId("3a9ccf7de6348936d88b3602"),
"first_name" : "Jane",
"last_name" : "Doe"
},
{
"_id" : ObjectId("3a9ccf7de6348936d88b3603"),
"first_name" : "Bobby",
"last_name" : "Doe"
}
]
RELATIONS
[
{
"_id" : ObjectId("5aa9a283e40f140014485116"),
"person_id" : ObjectId("3a9ccf7de6348936d88b3603"),
"parent_id" : ObjectId("3a9ccf7de6348936d88b3601"),
"position": "father"
},
{
"_id" : ObjectId("5aa9a283e40f140014485116"),
"person_id" : ObjectId("3a9ccf7de6348936d88b3603"),
"parent_id" : ObjectId("3a9ccf7de6348936d88b3602"),
"position": "mother"
}
]
I want something like this:
[
{
"_id" : ObjectId("3a9ccf7de6348936d88b3603"),
"first_name" : "Bobby",
"last_name" : "Doe",
"relations: : [
{
"_id" : ObjectId("3a9ccf7de6348936d88b3602"),
"first_name" : "Jane",
"last_name" : "Doe",
"position": "mother"
},
{
"_id" : ObjectId("3a9ccf7de6348936d88b3601"),
"first_name" : "John",
"last_name" : "Doe",
"position": "father"
}
]
}
]
I know I need aggregate and $lookup. but I cant get past the most basic
db.getCollection('people')
.aggregate([
{ $lookup: {
from: 'relations',
localField: 'person_id',
foreignField: '_id',
as: 'relations'
}
}
])
Upvotes: 2
Views: 85
Reputation: 5669
here's another way to do it using a nested lookup/sub-pipeline. also shows the position of relations.
db.people.aggregate(
[
{
$lookup:
{
from: 'relations',
let: { person_id: '$_id' },
pipeline: [
{
$match: {
$expr: { $eq: ["$person_id", "$$person_id"] }
}
},
{
$lookup: {
from: "people",
localField: "parent_id",
foreignField: "_id",
as: "person"
}
},
{
$replaceWith: {
$mergeObjects: [{ $arrayElemAt: ["$person", 0] }, "$$ROOT"]
}
},
{
$project: {
_id: "$parent_id",
position: 1,
first_name: 1,
last_name: 1
}
}
],
as: 'relations'
}
}
])
https://mongoplayground.net/p/EJB-1WfanuY
Upvotes: 0
Reputation: 49945
You need to run $lookup
twice and second one should have people
as a "from" value:
db.people.aggregate([
{
$lookup: {
from: "relations",
localField: "_id",
foreignField: "person_id",
as: "relations"
}
},
{
$lookup: {
from: "People",
localField: "relations._id",
foreignField: "_id",
as: "relations"
}
}
])
Upvotes: 1