updated 31 Jan, 2021
Join-like operation in MongoDB
SQL databases provide JOIN
operation: each row in the query result is provided with the related data found by the foreign key value.
The similar effect could be achieved in MongoDB if store child items as array in a collection record and use aggregate
/ unwind
function.
Example data
Let's have orders collection where each record contains array of items purchased:
> db.orders.save({ u:1, items:[{name:'Pencil', price:0.25}, {name: 'Pen', price: 0.19}] }) WriteResult({ "nInserted" : 1 }) > db.orders.save({ u:2, items:[{name:'Book', price:0.57}, {name: 'Pen', price: 0.19}] }) WriteResult({ "nInserted" : 1 }) > db.orders.find({}, {_id: 0}) {"u": 1, "items": [{ "name": "Pencil", "price": 0.25 }, { "name": "Pen", "price" :0.19 }]} {"u": 2, "items": [{"name": "Book", "price": 0.57 }, { "name": "Pen", "price": 0.19 }]}The second parameter tells to exclude the _id column from the output.
Query data
How to get items from several orders with the parent order record, like we join them:
> db.orders.aggregate([{$unwind: '$items'}]) { "_id" : ObjectId("...2e"), "u" : 1, "items" : { "name" : "Pencil", "price" : 0.25 } } { "_id" : ObjectId("...2e"), "u" : 1, "items" : { "name" : "Pen", "price" : 0.19 } } { "_id" : ObjectId("...2f"), "u" : 2, "items" : { "name" : "Book", "price" : 0.57 } } { "_id" : ObjectId("...2f"), "u" : 2, "items" : { "name" : "Pen", "price" : 0.19 } }The number of results is same as the number of items, each item is returned with its parent order.
We can make grouping on the item name then to calculate sum per item:
> db.orders.aggregate([ {$unwind: '$items'}, { $group: { _id: "$items.name", avg:{$sum: '$items.price'} } } ]) { "_id" : "Pencil", "avg" : 0.25 } { "_id" : "Book", "avg" : 0.57 } { "_id" : "Pen", "avg" : 0.38 }