I'm new to mongo and struggling mightily with the following. I have 2 collections structured as below. For the life of me, I can't figure out how to do a $lookup on the school collection. Reading other posts, I'm definitely using ObjectId for the reference as well as the foreign field.
Below is my structure:
Alumni:
{ "_id": "john", "items": [ { "name": "John", "items": [ { "school": ObjectId("56de35ab520fc05b2fa3d5e4"), "grad": true }, { "school": ObjectId("56de35ab520fc05b2fa00000"), "grad": false } ] }, { "name": "Johnny" // notice no nested items, this doc should still be included in result }, { "name": "Jon", "items": [ { "school": ObjectId("56de35ab520fc05b2fa11111"), "grad": false } ] } ] }
Schools
{ _id: ObjectId("56de35ab520fc05b2fa3d5e4"), name: "Some University", street: "ABC Boulevard" }
What I'm looking to get:
{ "_id": "john", "items": [ { "name": "John", "items": [ { "school": ObjectId("56de35ab520fc05b2fa3d5e4"), "grad": true, "schoolInfo": { _id: ObjectId("56de35ab520fc05b2fa3d5e4"), name: "Some University", street: "ABC Boulevard" } }, { "school": ObjectId("56de35ab520fc05b2fa00000"), "grad": true, "schoolInfo": { _id: ObjectId("56de35ab520fc05b2fa00000"), name: "Another University", street: "123 Boulevard" } } ] }, { name: "Johnny" }, { "name": "Jon", "items": [ { "school": ObjectId("56de35ab520fc05b2fa11111"), "grad": true, "schoolInfo": { _id: ObjectId("56de35ab520fc05b2fa11111"), name: "Some University", street: "ABC Boulevard" } } ] } ] }
The query I've tried to no avail:
db.alumni.aggregate([ {$match: {_id: 'john'}}, {$lookup: { from: 'schools', localField: 'items.items.school', foreignField: '_id', as: 'schoolInfo'}} ])
Any help would be greatly appreciated!
Accessing embedded/nested documents – In MongoDB, you can access the fields of nested/embedded documents of the collection using dot notation and when you are using dot notation, then the field and the nested field must be inside the quotation marks.
$lookup performs an equality match on the localField to the foreignField from the documents of the from collection. If an input document does not contain the localField , the $lookup treats the field as having a value of null for matching purposes.
For performing MongoDB Join two collections, you must use the $lookup operator. It is defined as a stage that executes a left outer join with another collection and aids in filtering data from joined documents.
in this case there is required a nice play with $unwind and $project in aggregation framework
please see below:
db.alumni.aggregate([ {$match: {_id: 'john'}}, {$unwind:"$items"}, {$unwind:"$items.items"}, {$lookup: { from: 'schools', localField: 'items.items.school', foreignField: '_id', as: 'schoolInfo'}}, {$unwind:"$schoolInfo"}, {$project:{ "_id":1, "items":[{ "name":"$items.name", "items":[{ "school":"$schoolInfo._id" , "grad":"$items.items.grad" , "schoolInfo":"$schoolInfo" }] }] }} ]).pretty()
to see how it works - try removing aggregation stages from query and check document structure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With