假设我有这种收藏品:
{
id : 1,
date : 2018-01-31 00:00:00
value : 1532
},
{
id : 1,
date : 2018-01-31 01:00:00
value : 1542
},
{
id : 1,
date : 2018-01-31 10:37:00
value : 1563
},
{
id : 1,
date : 2018-01-31 06:00:00
value : 1680
}
我必须创建一个增量mapreduce,以便在数据到达时使另一个集合存储消费,因此基本上,我的其他集合必须具有以下类型的数据:
{
id : 1,
date : 2018-01-31 01:00:00
value : 10 // 1542-1532
},
{
id : 1,
date : 2018-01-31 10:37:00
value : 21 // 1563-1542
},
{
id : 1,
date : 2018-01-31 06:00:00
value : 117 // 1680-1563
}
因此map减少了执行此操作的最佳解决方案,以及如何减少我的所有数据?
答案 0 :(得分:0)
您可以使用汇总框架$slice和$zip来计算连续文档之间的差异,如下所示:
db.col.aggregate([
{ $sort: { date: 1 } }, // only if you want records in chronological order based on date field instead of _id
{ $group: {
_id: "$id",
data: { $push: { date: "$date", value: "$value" } }
} },
{ $addFields: { shift: { $slice: [ "$data", 1, { $size: "$data" } ] } } },
{ $project: {
diff: {
$zip: { inputs: [ "$data", "$shift" ] }
}
} },
{ $unwind: "$diff" },
{ $project: {
_id: 0,
id: "$_id",
date: {
$let: {
vars: {
base: { $arrayElemAt: [ "$diff", 1 ] }
},
in: { $add: [ "$$base.date", 0 ] }
}
},
value: {
$let: {
vars: {
base: { $arrayElemAt: [ "$diff", 1 ] },
prev: { $arrayElemAt: [ "$diff", 0 ] }
},
in: { $subtract: [ "$$base.value", "$$prev.value" ] }
}
}
} }
];
它仍然在内部加倍数据集,当您检索所有id
的数据时,这是可以的。如果您需要单个id
的差异,最好的选择是执行简单find并计算差异客户端:
let prev;
db.col.find({ id: 1 }).map( doc => {
if (!prev) {
prev = doc;
return null;
}
const res = {date: doc.date, value: doc.value - prev.value};
prev = doc;
return res;
} ).slice(1);
在数据到达时迭代游标对性能的影响最小。请参阅客户端库的文档如何流式传输数据。