Reputation: 96
I have two collections Employees
, Clients
Employees
schema has following record
{
"_id" : ObjectId("5a852dcd0290f7eca89e9a79"),
"FirstName" : "raj",
"LastName" : "patel",
"Forms" : [{
"ClientId" : ObjectId("5a8528ed0290f7eca89e9a5f"),
"ProjectId" : ObjectId("5a856fde0290f7eca89e9a88"),
"FormId" : ObjectId("5a6eeb9e3bf43426d4d31774")
}, {
"ClientId" : ObjectId("5a87f593d59a6fb5249c72ad"),
"ProjectId" : ObjectId("5a87f593d59a6fb5249c72b1"),
"FormId" : ObjectId("5a6eec263bf43426d4d31780")
}, {
"ClientId" : ObjectId("5a8528ed0290f7eca89e9a5f"),
"ProjectId" : ObjectId("5a856d850290f7eca89e9a85"),
"FormId" : ObjectId("5a6eec263bf43426d4d31780")
}]
}
Clients
schema has following record
{
"_id" : ObjectId("5a8528ed0290f7eca89e9a5f"),
"CompanyName" : "test",
"Email" : "[email protected]",
"PhoneNumber" : "(987)654-3210",
"Projects" : [{
"_id" : ObjectId("5a856ca70290f7eca89e9a7f"),
"Name" : "Feedback",
"Description" : "Feedback form",
"Forms" : [
ObjectId("5a6eeace1a692b18b4a4ae3a"),
ObjectId("5a688a799109bd17b4e8c8b2")
]
}, {
"_id" : ObjectId("5a856d700290f7eca89e9a82"),
"Name" : "complaint",
"Description" : "sfsddsf !",
"Forms" : [
ObjectId("5a66d56ffe50af19647f66dd"),
ObjectId("5a66d4ccfe50af19647f66db"),
ObjectId("5a5f18169c50261c24ca5f0a")
]
}, {
"_id" : ObjectId("5a856d850290f7eca89e9a85"),
"Name" : "Test Project",
"Description" : "For testing purpose",
"Forms" : [
ObjectId("5a62e2a8f85cf41bd0a8f522"),
ObjectId("5a6eec263bf43426d4d31780")
]
}, {
"_id" : ObjectId("5a856fde0290f7eca89e9a88"),
"Name" : "simple project",
"Description" : "Project",
"Forms" : [
ObjectId("5a6eeb9e3bf43426d4d31774")
]
}
]
},{
"_id" : ObjectId("5a87f593d59a6fb5249c72ad"),
"CompanyName" : "PNB",
"Email" : "[email protected]",
"PhoneNumber" : "(987)654-3210",
"Projects" : [{
"_id" : ObjectId("5a87f593d59a6fb5249c72ae"),
"Name" : "Home Loan",
"Description" : "Get home loan!",
"Forms" : [
ObjectId("5a6eeb9e3bf43426d4d31774")
]
}, {
"_id" : ObjectId("5a87f593d59a6fb5249c72b1"),
"Name" : "Car Loan",
"Description" : "For testing purpose of android app",
"Forms" : [
ObjectId("5a6eec263bf43426d4d31780")
]
}
]
}
My output is like below
{
"_id" : "5a852dcd0290f7eca89e9a79",
"FirstName" : "raj",
"LastName" : "patel",
"Clients" : [{
"_id" : "5a87f593d59a6fb5249c72ad",
"CompanyName" : "PNB",
"Email" : "[email protected]",
"PhoneNumber" : "(987)654-3210",
"Projects" : [{
"_id" : "5a87f593d59a6fb5249c72b1",
"Name" : "Car Loan",
"Description" : "For testing purpose of android app",
"Forms" : [
"5a6eec263bf43426d4d31780"
]
}
]
}, {
"_id" : "5a8528ed0290f7eca89e9a5f",
"CompanyName" : "test",
"Email" : "[email protected]",
"PhoneNumber" : "(987)654-3210",
"Projects" : [{
"_id" : "5a856fde0290f7eca89e9a88",
"Name" : "simple project",
"Description" : "Project",
"Forms" : [
"5a6eeb9e3bf43426d4d31774"
]
}, {
"_id" : "5a856d850290f7eca89e9a85",
"Name" : "Test Project",
"Description" : "For testing purpose",
"Forms" : [
"5a62e2a8f85cf41bd0a8f522", // this first element of array should not come in result because it is not in Employee document
"5a6eec263bf43426d4d31780"
]
}
]
}
]
}
I want only that Forms
which is in Employees
document.In above 5a62e2a8f85cf41bd0a8f522
entry should not come because that entry is not in Employees
document
For this I am doing aggregation as below,
db.Employees.aggregate([{
$match: {
_id: ObjectId("5a852dcd0290f7eca89e9a79")
}
}, {
$unwind: "$Forms"
}, {
$lookup: {
from: "Clients",
localField: "Forms.ClientId",
foreignField: "_id",
as: "Clients"
}
}, {
$unwind: "$Clients"
}, {
$unwind: "$Clients.Projects"
}, {
$unwind: "$Clients.Projects.Forms"
}, {
$redact: {
$cond: {
if : {
$and: [{
$eq: ["$Forms.ProjectId", "$Clients.Projects._id"]
}, {
$eq: ["$Forms.FormId", "$Clients.Projects.Forms"]
}
]
},
then: "$$KEEP",
else : "$$PRUNE"
}
}
}, {
$group: {
_id: {
_id: "$_id",
ClientId: "$Clients._id",
ProjectId: "$Forms.ProjectId"
},
FirstName: {
$first: "$FirstName"
},
LastName: {
$first: "$LastName"
},
Client: {
$first: "$Clients"
},
Projects: {
$first: "$Clients.Projects"
},
Forms: {
$push: "$Clients.Projects.Forms"
}
}
}, {
$group: {
_id: {
_id: "$_id._id",
ClientId: "$Clients._id",
},
FirstName: {
$first: "$FirstName"
},
LastName: {
$first: "$LastName"
},
Client: {
$first: "$Client"
},
Projects: {
$push: {
_id: "$Projects._id",
Name: "$Projects.Name",
Description: "$Projects.Description",
Forms : "$Forms"
}
}
}
}, {
$group: {
_id: "$_id._id",
FirstName: {
$first: "$FirstName"
},
LastName: {
$first: "$LastName"
},
Clients: {
$push: {
_id: "$Client._id",
CompanyName: "$Client.CompanyName",
Email: "$Client.Email",
PhoneNumber: "$Client.PhoneNumber",
Projects: "$Projects"
}
}
}
}
]).pretty()
This is working fine for me, but i want only that form which is in Employees
document
Upvotes: 0
Views: 66
Reputation: 49945
There is one level of $unwind
/$group
pair missing here. Currently your $redact
stage get's as an input document like this:
{
"_id" : ObjectId("5a852dcd0290f7eca89e9a79"),
"FirstName" : "raj",
"LastName" : "patel",
"Forms" : {
"ClientId" : ObjectId("5a8528ed0290f7eca89e9a5f"),
"ProjectId" : ObjectId("5a856d850290f7eca89e9a85"),
"FormId" : ObjectId("5a6eec263bf43426d4d31780")
},
"Clients" : {
"_id" : ObjectId("5a8528ed0290f7eca89e9a5f"),
"CompanyName" : "test",
"Email" : "[email protected]",
"PhoneNumber" : "(987)654-3210",
"Projects" : {
"_id" : ObjectId("5a856d850290f7eca89e9a85"),
"Name" : "Test Project",
"Description" : "For testing purpose",
"Forms" : [
ObjectId("5a62e2a8f85cf41bd0a8f522"),
ObjectId("5a6eec263bf43426d4d31780")
]
}
}
}
So you're matching FormId
with an array of forms which will return true if any element of that array matches. You have to add
{
$unwind: "$Clients.Projects.Forms"
}
to match values with each other.
EDIT: Entire working aggregation:
db.Employees.aggregate([{
$match: {
_id: ObjectId("5a852dcd0290f7eca89e9a79")
}
}, {
$unwind: "$Forms"
}, {
$lookup: {
from: "Clients",
localField: "Forms.ClientId",
foreignField: "_id",
as: "Clients"
}
}, {
$unwind: "$Clients"
}, {
$unwind: "$Clients.Projects"
}, {
$unwind: "$Clients.Projects.Forms"
}, {
$redact: {
$cond: {
if : {
$and: [{
$eq: ["$Forms.ProjectId", "$Clients.Projects._id"]
}, {
$eq: ["$Forms.FormId", "$Clients.Projects.Forms"]
}
]
},
then: "$$KEEP",
else : "$$PRUNE"
}
}
}, {
$group: {
_id: {
_id: "$_id",
ClientId: "$Clients._id",
ProjectId: "$Clients.Projects._id"
},
FirstName: {
$first: "$FirstName"
},
LastName: {
$first: "$LastName"
},
Client: {
$first: "$Clients"
},
Projects: {
$first: "$Clients.Projects"
},
Forms: {
$push: "$Clients.Projects.Forms"
}
}
}, {
$group: {
_id: {
_id: "$_id._id",
ClientId: "$_id.ClientId",
},
FirstName: {
$first: "$FirstName"
},
LastName: {
$first: "$LastName"
},
Client: {
$first: "$Client"
},
Projects: {
$push: {
_id: "$Projects._id",
Name: "$Projects.Name",
Description: "$Projects.Description",
Forms : "$Forms"
}
}
}
}, {
$group: {
_id: "$_id._id",
FirstName: {
$first: "$FirstName"
},
LastName: {
$first: "$LastName"
},
Clients: {
$push: {
_id: "$Client._id",
CompanyName: "$Client.CompanyName",
Email: "$Client.Email",
PhoneNumber: "$Client.PhoneNumber",
Projects: "$Projects"
}
}
}
}
]).pretty()
Upvotes: 1