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 thecollection
collection and return thebars
array field. -
$set
– Setfoo
array.2.1.
$map
– Iterate element infoo
array.2.1.1.
$mergeObjects
– Merge current iteratedfoo
element with the result of 2.1.1.1.2.1.1.1. A document with a
bar
field which contains the result of 2.1.1.1.1.2.1.1.1.1.
$map
– Iterate element inbar
array.2.1.1.1.1.1.
$mergeObjects
– Merge the current iteratedbar
element 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 thebars
array by_id
s. -
$unset
– Removebars
array.
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"
}
])