I’m trying to populate a double array object but in an aggregate so I am utilizing the $lookup function. The collection looks something like this:
{
foo: [
{
bar: [
{
_id: ObjectId('63f508eedd2962118c37ea36')
}
]
}
]
}
My lookup looks like:
{
$lookup: {
from: "collection",
localField: "foo.bar",
foreignField: "_id",
as: "foo.bar",
},
}
which results in
{
foo: {
bar: [
{
_id: ObjectId('63f508eedd2962118c37ea36'),
field1: "helloworld"
}
]
}
}
where what I actually want is
{
foo: [
{
bar: [
{
_id: ObjectId('63f508eedd2962118c37ea36'),
field1: "helloworld"
}
]
}
]
}
Any ideas on how to achieve what I want in an aggregate?
>Solution :
Seems a direct map with $lookup for the nested array is not possible.
-
$lookup– Join thecollectioncollection and return thebarsarray field. -
$set– Setfooarray.2.1.
$map– Iterate element infooarray.2.1.1.
$mergeObjects– Merge current iteratedfooelement with the result of 2.1.1.1.2.1.1.1. A document with a
barfield which contains the result of 2.1.1.1.1.2.1.1.1.1.
$map– Iterate element inbararray.2.1.1.1.1.1.
$mergeObjects– Merge the current iteratedbarelement with the result of 2.1.1.1.1.1.1.2.1.1.1.1.1.1.
$first– Get the first matching element from thebarsarray by_ids. -
$unset– Removebarsarray.
db.from.aggregate([
{
$lookup: {
from: "collection",
localField: "foo.bar._id",
foreignField: "_id",
as: "bars"
}
},
{
$set: {
foo: {
$map: {
input: "$foo",
as: "foo",
in: {
$mergeObjects: [
"$$foo",
{
bar: {
$map: {
input: "$$foo.bar",
as: "bar",
in: {
$mergeObjects: [
"$$bar",
{
$first: {
$filter: {
input: "$bars",
cond: {
$eq: [
"$$bar._id",
"$$this._id"
]
}
}
}
}
]
}
}
}
}
]
}
}
}
}
},
{
$unset: "bars"
}
])