Reputation: 61
I have the following result. Below it would be possible to make a map joining the array each with its objectid.
{
"_id": ObjectId("597233b50e717e0585dbd94a"),
"createdAt": ISODate("2017-07-21T17:02:45.119+0000"),
"name": "cardoso",
"gender": "female",
"profile": [{
"profession": "master",
"_id": ObjectId("597233b50e717e0585dbd94b"),
"departament": ObjectId("597233b50e717e0585dbd94e")
},
{
"_id": ObjectId("59766719003e7d552fe40e8c"),
"profession": "master",
"departament": ObjectId("59766719003e7d552fe40e8b")
},
{
"_id": ObjectId("5976b8f99d8a4326c6bf1ae5"),
"profession": "master",
"departament": ObjectId("5974d8fe398e5b2fd433410f")
}
],
"Institution": {
"_id": ObjectId("597233b50e717e0585dbd94c"),
"cnpj": 64837134000144.0,
"deletedAt": false,
"departament": [{
"title": "cardoso",
"category": "Sub-17",
"_id": ObjectId("597233b50e717e0585dbd94e")
},
{
"sport": "Tênis",
"title": "novo",
"category": "Sub-12",
"_id": ObjectId("59766719003e7d552fe40e8b")
},
{
"_id": ObjectId("5974d8fe398e5b2fd433410f"),
"category": "Intercâmbio",
"title": "testeJJJ",
"sport": "natação"
}
]
}
}
I need to do the following result. I did not want to have to manipulate the result in the node.
{
"sport": "Tênis",
"profession": "master",
"title": "novo",
"category": "Sub-12",
"_id": ObjectId("59766719003e7d552fe40e8b")
}
I already tended to do something but the query ends up getting very big
Upvotes: 2
Views: 49
Reputation: 151170
The basic premise here is to "lookup" the content in the other array whilst processing via $map
.
This is either done via $indexOfArray
with MongoDB 3.4:
db.collection.aggregate([
{ "$addFields": {
"Institution": {
"departament": {
"$map": {
"input": "$Institution.departament",
"as": "d",
"in": {
"sport": "$$d.title",
"profession": {
"$arrayElemAt": [
"$profile.profession",
{ "$indexOfArray": [ "$profile.departament", "$$d._id" ] }
]
},
"title": "$$d.title",
"category": "$$d.category"
}
}
}
}
}}
])
In that first index we look for the "index position" from the "profile"
array that matches the current value of _id
on the specified field. Then extract the data at that index via $arrayElemAt
.
Or using $filter
and the $arrayElemAt
"the other way around" with MongoDB 3.2:
db.collection.aggregate([
{ "$addFields": {
"Institution": {
"departament": {
"$map": {
"input": "$Institution.departament",
"as": "d",
"in": {
"sport": "$$d.title",
"profession": {
"$arrayElemAt": [
{ "$map": {
"input": {
"$filter": {
"input": "$profile",
"as": "p",
"cond": { "$eq": [ "$$p.departament", "$$d._id" ] }
}
},
"as": "p",
"in": "$$p.profession"
}},
0
]
},
"title": "$$d.title",
"category": "$$d.category"
}
}
}
}
}}
])
In which case the $filter
reduces the array content in "profile"
down to only matching elements, which should be just one. This is then extracted at the 0
index by $arrayElemAt
.
Same result in either case:
{
"_id" : ObjectId("597233b50e717e0585dbd94a"),
"createdAt" : ISODate("2017-07-21T17:02:45.119Z"),
"name" : "cardoso",
"gender" : "female",
"profile" : [
{
"profession" : "master",
"_id" : ObjectId("597233b50e717e0585dbd94b"),
"departament" : ObjectId("597233b50e717e0585dbd94e")
},
{
"_id" : ObjectId("59766719003e7d552fe40e8c"),
"profession" : "master",
"departament" : ObjectId("59766719003e7d552fe40e8b")
},
{
"_id" : ObjectId("5976b8f99d8a4326c6bf1ae5"),
"profession" : "master",
"departament" : ObjectId("5974d8fe398e5b2fd433410f")
}
],
"Institution" : {
"_id" : ObjectId("597233b50e717e0585dbd94c"),
"cnpj" : 64837134000144.0,
"deletedAt" : false,
"departament" : [
{
"sport" : "cardoso",
"profession" : "master",
"title" : "cardoso",
"category" : "Sub-17"
},
{
"sport" : "novo",
"profession" : "master",
"title" : "novo",
"category" : "Sub-12"
},
{
"sport" : "testeJJJ",
"profession" : "master",
"title" : "testeJJJ",
"category" : "Intercâmbio"
}
]
}
}
Upvotes: 1