【问题标题】:Mongodb calculation query--cummulative multiplicationMongodb计算查询--累积乘法
【发布时间】:2018-03-22 14:13:33
【问题描述】:

我最近开始在 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 但没有运气。你们可以帮助或建议一些方法吗?

【问题讨论】:

  • 能否提供sales的公式?因为这些例子没有多大帮助。

标签: mongodb calculation


【解决方案1】:

您可以使用以下聚合:

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的数组($group中的$push
  • n 表示您必须执行多少次乘法

要计算索引,您应该将所有元素$push 放入一个数组中,然后使用$unwindincludeArrayIndex 选项将展开数组的索引插入字段index

最后一步计算累积乘法。它使用$sliceindex 字段来评估应该处理多少growths。所以601 将有一个元素,602 将有两个元素,依此类推。

然后是$reduce 处理该数组并根据您的公式执行乘法运算的时候了:(1 + (growth/100))

【讨论】:

  • $slice 规范更改为 $slice: [ "$growths", 1, "$index" ] 以正确偏移切片。否则很好的解决方案!
  • @DonnyWinston 我做不到。 growths 是两个组中的 2 元素数组,因为每个组中的第一个文档没有 growth,所以不需要有偏移量
  • @mickl 感谢您的回答!你能给我一些建议吗? 加强MongoDB聚合?
  • @Buddi 我相信编写代码是学习编程的最佳方式 :) 在这种情况下,MongoDB 有非常有用的文档。感谢您提出非常有趣的问题!
  • @mickl 谢谢,你是对的!我认为对于没有“增长”字段的文档,空值将是 $pushed,但你是对的,它是一个 2 元素数组。感谢您的澄清!
猜你喜欢
  • 2013-02-24
  • 1970-01-01
  • 2020-08-07
  • 2019-07-01
  • 1970-01-01
  • 2019-06-06
  • 1970-01-01
  • 2020-12-17
  • 2021-12-22
相关资源
最近更新 更多