Mongoose Join List
We can use $lookup to merge the documents in two different collections of same database and it performs a left outer join on the collections.
Let us the below documents in content
collection
{ "_id" : ObjectId("59ef51f106b0505f997f84c8"), "title" : "myfavoritesong", "description" : "A wonderful composition using string instruments"}{ "_id" : ObjectId("59ef52ad06b0505f997f84ca"), "title" : "myfavoritestory", "description" : "An interesting short story with a twisted ending"}
Documents in viewed
collection
{ "_id" : ObjectId("59ef523706b0505f997f84c9"), "contentid" : ObjectId("59ef51f106b0505f997f84c8"), "viewedby" : "user1"}{ "_id" : ObjectId("59ef52f406b0505f997f84cb"), "contentid" : ObjectId("59ef52ad06b0505f997f84ca"), "viewedby" : "user2"}{ "_id" : ObjectId("59ef53c706b0505f997f84cc"), "contentid" : ObjectId("59ef52ad06b0505f997f84ca"), "viewedby" : "user3"}
Final aggregate query using $lookup by combining the two collections is
db.viewed.aggregate({ $lookup:{ from : "content", localField: "contentid", foreignField:"_id", as:"viewed_contents" }})
Result of the aggregate query for our sample data is
{ "_id" : ObjectId("59ef523706b0505f997f84c9"), "contentid" : ObjectId("59ef51f106b0505f997f84c8"), "viewedby" : "user1", "viewed_contents" : [ { "_id" : ObjectId("59ef51f106b0505f997f84c8"), "title" : "myfavoritesong", "description" : "A wonderful composition using string instruments" } ]}{ "_id" : ObjectId("59ef52f406b0505f997f84cb"), "contentid" : ObjectId("59ef52ad06b0505f997f84ca"), "viewedby" : "user2", "viewed_contents" : [ { "_id" : ObjectId("59ef52ad06b0505f997f84ca"), "title" : "myfavoritestory", "description" : "An interesting short story with a twisted ending" } ]}{ "_id" : ObjectId("59ef53c706b0505f997f84cc"), "contentid" : ObjectId("59ef52ad06b0505f997f84ca"), "viewedby" : "user3", "viewed_contents" : [ { "_id" : ObjectId("59ef52ad06b0505f997f84ca"), "title" : "myfavoritestory", "description" : "An interesting short story with a twisted ending" } ]}
Please note you can also swap the collections from viewed
as foreign and content
as local
db.content.aggregate({ $lookup:{ from : "viewed", localField: "_id", foreignField:"contentid", as:"contents_viewed_by" }})
Result of this aggregate query is as follows
{ "_id" : ObjectId("59ef51f106b0505f997f84c8"), "title" : "myfavoritesong", "description" : "A wonderful composition using string instruments", "contents_viewed_by" : [ { "_id" : ObjectId("59ef523706b0505f997f84c9"), "contentid" : ObjectId("59ef51f106b0505f997f84c8"), "viewedby" : "user1" } ]}{ "_id" : ObjectId("59ef52ad06b0505f997f84ca"), "title" : "myfavoritestory", "description" : "An interesting short story with a twisted ending", "contents_viewed_by" : [ { "_id" : ObjectId("59ef52f406b0505f997f84cb"), "contentid" : ObjectId("59ef52ad06b0505f997f84ca"), "viewedby" : "user2" }, { "_id" : ObjectId("59ef53c706b0505f997f84cc"), "contentid" : ObjectId("59ef52ad06b0505f997f84ca"), "viewedby" : "user3" } ]}