我正在使用MongoDB 3.4,我需要创建一个查询过滤器以从我的mongo集合(ProductionEventsCollection
)中获取数据。
有些值是“ 即时”计算的。
由于这些记录是基于事件的,并且将来的值取决于过去的值,因此,如果过去更改某个值,则会影响将来的总和。
我有一个集合,其属性如下所示:
[{
_id: "5bfc2a16b4f11f3760ed4b64",
piece_id: "12345",
finish_date: "2018-11-26T17:15:09.795Z",
total_produced: 500
},
{
_id: "5bfc2a16b4f11f3760ed4b65",
piece_id: "12345",
finish_date: "2018-11-27T17:15:09.795Z",
total_produced: 750
},
{
_id: "5bfc2a16b4f11f3760ed4b66",
piece_id: "12345",
finish_date: "2018-11-28T17:15:09.795Z",
total_produced: 250
}]
想法是获得这样的收藏:
[{
_id: "5bfc2a16b4f11f3760ed4b64",
piece_id: "12345",
finish_date: "2018-11-26T17:15:09.795Z",
previous_value: 0,
total_produced: 500,
new_value: 500
},
{
_id: "5bfc2a16b4f11f3760ed4b65",
piece_id: "12345",
finish_date: "2018-11-27T17:15:09.795Z",
previous_value: 500,
total_produced: 750,
new_value: 1250
},
{
_id: "5bfc2a16b4f11f3760ed4b66",
piece_id: "12345",
finish_date: "2018-11-28T17:15:09.795Z",
previous_value: 1250,
total_produced: 250,
new_value: 1500
}]
基于finish_date
属性,我应该能够计算到该日期之前的previous_value
和,而new_value
将是先前计算的总和加上total_produced
上一个值
previous_value = SUM(past total_produced) until finish_date
新价值
new_value = previous_value + total_produced
基于这些集合值,我需要返回一个json数组,因为我将允许用户下载电子表格。
答案 0 :(得分:1)
您可以尝试在汇总下面获取结果,逻辑是使用$reduce
来计算运行总计
聚合管道
db.t32.aggregate([
{$group : {_id : "$piece_id", data : {$push : "$$ROOT"}}},
{$addFields : {data :
{$reduce : {
input : "$data",
initialValue : [{previous_value : 0, total_produced : 0, new_value : 0}],
in : {$concatArrays :
[ "$$value",[{$mergeObjects : ["$$this", { previous_value : {$arrayElemAt : ["$$value.new_value", -1]} , total_produced : "$$this.total_produced", new_value : {$sum : ["$$this.total_produced",{$arrayElemAt : ["$$value.new_value", -1]}]}}]}]]
}
}}
}},
{$addFields : {data : {$slice : ["$data", 1, {$size : "$data"}]}}}
]).pretty()
样品采集
> db.t32.find()
{ "_id" : "5bfc2a16b4f11f3760ed4b64", "piece_id" : "12345", "finish_date" : "2018-11-26T17:15:09.795Z", "total_produced" : 500 }
{ "_id" : "5bfc2a16b4f11f3760ed4b65", "piece_id" : "12345", "finish_date" : "2018-11-27T17:15:09.795Z", "total_produced" : 750 }
{ "_id" : "5bfc2a16b4f11f3760ed4b66", "piece_id" : "12345", "finish_date" : "2018-11-28T17:15:09.795Z", "total_produced" : 250 }
汇总结果
> db.t32.aggregate([
... {$group : {_id : "$piece_id", data : {$push : "$$ROOT"}}},
... {$addFields : {data :
... {$reduce : {
... input : "$data",
... initialValue : [{previous_value : 0, total_produced : 0, new_value : 0}],
... in : {$concatArrays :
... [ "$$value",[{$mergeObjects : ["$$this", { previous_value : {$arrayElemAt : ["$$value.new_value", -1]} , total_produced : "$$this.total_produced", new_value : {$sum : ["$$this.total_produced",{$arrayElemAt : ["$$value.new_value", -1]}]}}]}]]
... }
... }}
... }},
... {$addFields : {data : {$slice : ["$data", 1,1000]}}}
... ]).pretty()
{
"_id" : "12345",
"data" : [
{
"_id" : "5bfc2a16b4f11f3760ed4b64",
"piece_id" : "12345",
"finish_date" : "2018-11-26T17:15:09.795Z",
"total_produced" : 500,
"previous_value" : 0,
"new_value" : 500
},
{
"_id" : "5bfc2a16b4f11f3760ed4b65",
"piece_id" : "12345",
"finish_date" : "2018-11-27T17:15:09.795Z",
"total_produced" : 750,
"previous_value" : 500,
"new_value" : 1250
},
{
"_id" : "5bfc2a16b4f11f3760ed4b66",
"piece_id" : "12345",
"finish_date" : "2018-11-28T17:15:09.795Z",
"total_produced" : 250,
"previous_value" : 1250,
"new_value" : 1500
}
]
}
>
答案 1 :(得分:0)
我不确定在mongodb中是否可以进行这种聚合。 听起来像是服务器端的典型业务逻辑,因此我建议将相关数据提取到服务器并在那里进行所有计算。这样一来,事情变得简单得多,并且没有任何性能损失。