I had a problem with mongodb aggregation with more than 2 collections. Here i represent my collections.
First Collection: potential
{
"_id" : ObjectId("5a0d1cb1d2fffa95ed85b3ba"),
"potential_id" : "P-00012347",
"potential_name" : "NKCL"}
My second collection: office
{
"_id" : ObjectId("5a0d20e8d2fffa95ed85b5bc"),
"potential_id" : "P-00012347",
"potential_name" : "NKCL",
"revision_id" : "R0",
"office_name" : "Marketing office",
"vertical_info" : [
{
"vertical_name" : "MEP",
"estimated_team" : "Marketing"
},
{
"vertical_name" : "BIM",
"estimated_team" : "Marketing"
},
{
"vertical_name" : "V1",
"estimated_team" : "Marketing"
}
]}
My third collection: services
{
"_id" : ObjectId("5a0d212cd2fffa95ed85b5e6"),
"potential_id" : "P-00012347",
"potential_name" : "NKCL",
"revision_id" : "R0",
"office_name" : "Marketing office",
"vertical_name" : "MEP",
"service_info" : [
{
"service_name" : "Service 1",
"total_cost" : 1
},
{
"service_name" : "Service 2",
"total_cost" : 2
}
]}
My fourth collection: servicebuild
{
"_id" : ObjectId("5a0d2175d2fffa95ed85b612"),
"potential_id" : "P-00012347",
"potential_name" : "NKCL",
"revision_id" : "R0",
"office_name" : "Marketing office",
"vertical_name" : "MEP",
"service_name" : "Service 1",
"service_building_info" : [
{
"building_no" : 1,
"building_name" : "Building 1"
},
{
"building_no" : 2,
"building_name" : "Building 2"
},
{
"building_no" : 3,
"building_name" : "Building 3"
}
]}
Now i want to join the above 4 collections with in a single aggregation query. I saw the most of the examples to join only the two collections.
My output look like this
{
"_id" : ObjectId("5a0d1cb1d2fffa95ed85b3ba"),
"potential_id" : "P-00012347",
"potential_name" : "NKCL"
"revision_id" : "R0",
"office_name" : "Marketing office",
"vertical_info" : [
{
"vertical_name" : "MEP",
"estimated_team" : "Marketing"
"service_info" : [
{
"service_name" : "Service 1",
"total_cost" : 1
"service_building_info" : [
{
"building_no" : 1,
"building_name" : "Building 1"
},
{
"building_no" : 2,
"building_name" : "Building 2"
},
{
"building_no" : 3,
"building_name" : "Building 3"
}
]
},
{
"service_name" : "Service 2",
"total_cost" : 2
}
]
},
{
"vertical_name" : "BIM",
"estimated_team" : "Marketing"
},
{
"vertical_name" : "V1",
"estimated_team" : "Marketing"
}]}
Anyone can help to solve my problem.
Here is the aggregation which results your desired output:
db.potential.aggregate([{
$lookup: {
from: 'office',
localField: 'potential-id',
foreignField: 'potential-id',
as: 'office'
}
},
{
$unwind: '$office'
},
{
$project: {
potential_id: 1,
potential_name: 1,
revision_id: '$office.revision_id',
office_name: '$office.office_name',
vertical_info: '$office.vertical_info'
}
},
{
$lookup: {
from: 'services',
localField: 'vertical_info.vertical_name',
foreignField: 'vertical_name',
as: 'services'
}
},
{
$project: {
potential_id: 1,
potential_name: 1,
revision_id: 1,
office_name: 1,
vertical_info: {
$map: {
input: '$vertical_info',
as: 'vertical_info_item',
in: {
vertical_name: '$$vertical_info_item.vertical_name',
estimated_team: '$$vertical_info_item.estimated_team',
service_info: {
$filter: {
input: '$services',
as: 'service',
cond: {
$eq: ['$$vertical_info_item.vertical_name', '$$service.vertical_name']
}
}
}
}
}
}
}
},
{
$project: {
potential_id: 1,
potential_name: 1,
revision_id: 1,
office_name: 1,
vertical_info: {
$map: {
input: '$vertical_info',
as: 'vertical_info_item',
in: {
vertical_name: '$$vertical_info_item.vertical_name',
estimated_team: '$$vertical_info_item.estimated_team',
service_info: {
$arrayElemAt: ['$$vertical_info_item.service_info.service_info', 0]
}
}
}
}
}
},
{
$lookup: {
from: 'servicebuild',
localField: 'vertical_info.service_info.service_name',
foreignField: 'service_name',
as: 'servicebuild'
}
},
{
$project: {
potential_id: 1,
potential_name: 1,
revision_id: 1,
office_name: 1,
vertical_info: {
$map: {
input: '$vertical_info',
as: 'vertical_info_item',
in: {
vertical_name: '$$vertical_info_item.vertical_name',
estimated_team: '$$vertical_info_item.estimated_team',
service_info: {
$map: {
input: '$$vertical_info_item.service_info',
as: 'service_info_item',
in: {
service_name: '$$service_info_item.service_name',
total_cost: '$$service_info_item.total_cost',
service_building_info: {
$filter: {
input: '$servicebuild',
as: 'servicebuild_item',
cond: {
$eq: ['$$service_info_item.service_name', '$$servicebuild_item.service_name']
}
}
}
}
}
}
}
}
}
}
},
{
$project: {
potential_id: 1,
potential_name: 1,
revision_id: 1,
office_name: 1,
vertical_info: {
$map: {
input: '$vertical_info',
as: 'vertical_info_item',
in: {
$cond: {
if: {
$ne: ['$$vertical_info_item.service_info', null]
},
then: {
vertical_name: '$$vertical_info_item.vertical_name',
estimated_team: '$$vertical_info_item.estimated_team',
service_info: {
$map: {
input: '$$vertical_info_item.service_info',
as: 'service_info_item',
in: {
service_name: '$$service_info_item.service_name',
total_cost: '$$service_info_item.total_cost',
service_building_info: {
$filter: {
input: '$$service_info_item.service_building_info',
as: 'servicebuild_item',
cond: {
$eq: ['$$service_info_item.service_name', '$$servicebuild_item.service_name']
}
}
}
}
}
}
},
else: {
vertical_name: '$$vertical_info_item.vertical_name',
estimated_team: '$$vertical_info_item.estimated_team'
}
}
}
}
}
}
},
{
$project: {
potential_id: 1,
potential_name: 1,
revision_id: 1,
office_name: 1,
vertical_info: {
$map: {
input: '$vertical_info',
as: 'vertical_info_item',
in: {
$cond: {
if: {
$ne: ['$$vertical_info_item.service_info', undefined]
},
then: {
vertical_name: '$$vertical_info_item.vertical_name',
estimated_team: '$$vertical_info_item.estimated_team',
service_info: {
$map: {
input: '$$vertical_info_item.service_info',
as: 'service_info_item',
in: {
service_name: '$$service_info_item.service_name',
total_cost: '$$service_info_item.total_cost',
service_building_info: {
$arrayElemAt: ['$$service_info_item.service_building_info.service_building_info', 0]
}
}
}
}
},
else: {
vertical_name: '$$vertical_info_item.vertical_name',
estimated_team: '$$vertical_info_item.estimated_team'
}
}
}
}
}
}
}
])
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.