Mongodb计算查询--累计乘法
Mongodb calculation query--cummulative multiplication
我最近开始在 Mongodb 从事 POC 工作。我下面有一个json合集
db.ccpsample.insertMany([
{
"ccp_id":1,
"period":601,
"sales":100.00
},
{
"ccp_id":1,
"period":602,
"growth":2.0,
"sales":"NULL" ##sales=100.00*(1+(2.0/100)) -- 100.00 comes from(ccp_id:1 and period=601)
},
{
"ccp_id":1,
"period":603,
"growth":3.0,
"sales":"NULL" ##sales=100.00*(1+(2.0/100))**(1+(3.0/100))-- 100.00 comes from(ccp_id:1 and period=601) 2.0 comes from (ccp_id:2 and period=602)
},
{
"ccp_id":2,
"period":601,
"sales":200.00
},
{
"ccp_id":2,
"period":602,
"growth":2.0,
"sales":"NULL" ##sales=200.00*(1+(2.0/100))
},
{
"ccp_id":2,
"period":603,
"growth":3.0,
"sales":"NULL" ##same like above
}
])
并且我需要使用上面的文档来计算具有 NULL 的销售字段,匹配条件 ccp_id 应该相同并且期间字段应该等于 601。我添加了一行来演示销售字段的计算在上面的集合中。我尝试使用 $graphlookup 但没有运气。你们能帮忙或提出一些建议吗?
您可以使用以下聚合:
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 ] }] } ] }
}
}
}
}
}
}
])
基本上要计算 n-th
元素的值,您必须了解以下内容:
- 第一个元素的销售额(
$first
in $group
)
- 所有
growths
的数组($push
in $group
)
n
指示您必须执行多少次乘法
要计算索引,您应该 $push
将所有元素放入一个数组中,然后使用 $unwind
和 includeArrayIndex
选项,这会将展开数组的索引插入字段 index
.
最后一步计算累积乘法。它使用 $slice 和 index
字段来评估应该处理多少 growths
。因此 601
有一个元素,602
有两个元素,依此类推。
然后是 $reduce 处理该数组并根据您的公式执行乘法的时候了:(1 + (growth/100)
)
我最近开始在 Mongodb 从事 POC 工作。我下面有一个json合集
db.ccpsample.insertMany([
{
"ccp_id":1,
"period":601,
"sales":100.00
},
{
"ccp_id":1,
"period":602,
"growth":2.0,
"sales":"NULL" ##sales=100.00*(1+(2.0/100)) -- 100.00 comes from(ccp_id:1 and period=601)
},
{
"ccp_id":1,
"period":603,
"growth":3.0,
"sales":"NULL" ##sales=100.00*(1+(2.0/100))**(1+(3.0/100))-- 100.00 comes from(ccp_id:1 and period=601) 2.0 comes from (ccp_id:2 and period=602)
},
{
"ccp_id":2,
"period":601,
"sales":200.00
},
{
"ccp_id":2,
"period":602,
"growth":2.0,
"sales":"NULL" ##sales=200.00*(1+(2.0/100))
},
{
"ccp_id":2,
"period":603,
"growth":3.0,
"sales":"NULL" ##same like above
}
])
并且我需要使用上面的文档来计算具有 NULL 的销售字段,匹配条件 ccp_id 应该相同并且期间字段应该等于 601。我添加了一行来演示销售字段的计算在上面的集合中。我尝试使用 $graphlookup 但没有运气。你们能帮忙或提出一些建议吗?
您可以使用以下聚合:
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 ] }] } ] }
}
}
}
}
}
}
])
基本上要计算 n-th
元素的值,您必须了解以下内容:
- 第一个元素的销售额(
$first
in$group
) - 所有
growths
的数组($push
in$group
) n
指示您必须执行多少次乘法
要计算索引,您应该 $push
将所有元素放入一个数组中,然后使用 $unwind
和 includeArrayIndex
选项,这会将展开数组的索引插入字段 index
.
最后一步计算累积乘法。它使用 $slice 和 index
字段来评估应该处理多少 growths
。因此 601
有一个元素,602
有两个元素,依此类推。
然后是 $reduce 处理该数组并根据您的公式执行乘法的时候了:(1 + (growth/100)
)