My invoices
collection looks something like this:
[
{
inv_name: 'Client 1',
inv_date: 2022-12-20T05:09:09.803Z,
inv_ready: false,
inv_payments: [
{
id: '123',
pay_amount: 32.45
},
{
id: '456',
pay_amount: 55.60
}
]
},
{
inv_name: 'Client 2',
inv_date: 2022-12-19T05:09:09.803Z,
inv_ready: true,
inv_paymenents: [
{
id: '459',
pay_amount: 67.45
},
{
id: '556',
pay_amount: 30.60
}
]
}]
I know how to create an array of just the subdocs using $project
and $unwind
. The goal is to just add some data from the parent document to each object like this.
[
{
id: '123',
pay_amount: 32.45,
inv_name: 'Client 1'
},
{
id: '456',
pay_amount: 55.60
inv_name: 'Client 1'
},
{
id: '459',
pay_amount: 67.45
inv_name: 'Client 2'
},
{
id: '556',
pay_amount: 30.60
inv_name: 'Client 2'
}]
Here is what I tried:
{"$project": {
_id: 0,
"inv_payments": {
$reduce: {
input: "$inv_payments",
initialValue: [],
in: {
$concatArrays: [
[{
client: "$this.name",
pay_id: "$$this.id",
pay_amount: "$$this.pay_amount"
}],
"$inv_payments"
]
}
}
}
}
},
{
$unwind: "$inv_payments"
},
{
$replaceRoot: {
newRoot: "$inv_payments"
}
}
])
I think I am close. I am not sure where the bug is. Any ideas would be greatly appreciated!
CodePudding user response:
Besides the typo error mentioned in the comment, the way you used the $reduce
operator is incorrect. You didn't work with the accumulator variable ($$value
).
Rather than using $reduce
, use the $map
operator which is simpler in your scenario:
Solution 1: $map
{
"$project": {
_id: 0,
"inv_payments": {
$map: {
input: "$inv_payments",
in: {
client: "$inv_name",
pay_date: "$$this.id",
pay_amount: "$$this.pay_amount"
}
}
}
}
}
Demo ($map
) @ Mongo Playground
Solution 2: $reduce
For $reduce
operator, your query should be:
{
"$project": {
_id: 0,
"inv_payments": {
$reduce: {
input: "$inv_payments",
initialValue: [],
in: {
$concatArrays: [
[
{
client: "$inv_name",
pay_date: "$$this.id",
pay_amount: "$$this.pay_amount"
}
],
"$$value"
]
}
}
}
}
}