Você pode usar a agregação abaixo:
db.ccpsample.aggregate([
{ $sort: { ccp_id: 1, period: 1 } },
{
$group: {
_id: "$ccp_id",
items: { $push: "$$ROOT" },
baseSale: { $first: "$sales" },
growths: { $push: "$growth" }
}
},
{
$unwind: {
path: "$items",
includeArrayIndex: "index"
}
},
{
$project: {
cpp_id: "$items.cpp_id",
period: "$items.period",
growth: "$items.growth",
sales: {
$cond: {
if: { $ne: [ "$items.sales", "NULL" ] },
then: "$items.sales",
else: {
$reduce: {
input: { $slice: [ "$growths", "$index" ] },
initialValue: "$baseSale",
in: { $multiply: [ "$$value", { $add: [1, { $divide: [ "$$this", 100 ] }] } ] }
}
}
}
}
}
}
])
Basicamente para calcular o valor de
n-th
elemento você tem que saber as seguintes coisas:- valor de venda do primeiro elemento (
$first
em$group
) - a matriz de todos os
growths
($push
em$group
) - o
n
que indica quantas multiplicações você tem que realizar
Para calcular o índice você deve
$push
todos os elementos em uma matriz e, em seguida, use $unwind
com includeArrayIndex
opção que irá inserir o índice do array desenrolado no campo index
. A última etapa calcula a multiplicação cumulativa. Ele usa $slice com
index
campo para avaliar quantos growths
deve ser processado. Portanto, haverá um elemento para 601
, dois elementos para 602
e assim por diante. Então é hora de $reduce para processar essa matriz e realizar as multiplicações com base em sua fórmula:(
1 + (growth/100)
)