如何使用mongodb中的聚合管道或地图缩小来计算集合中每年最小和最大日期的记录的特定列的值的差异?
我有以下系列:
/* 1 */
{
"_id" : 1,
"item" : "abc",
"price" : 10,
"quantity" : 2,
"date" : ISODate("2014-01-01T08:00:00.000Z")
},
/* 2 */
{
"_id" : 2,
"item" : "jkl",
"price" : 20,
"quantity" : 1,
"date" : ISODate("2014-02-03T09:00:00.000Z")
},
/* 3 */
{
"_id" : 3,
"item" : "xyz",
"price" : 5,
"quantity" : 5,
"date" : ISODate("2014-02-03T09:05:00.000Z")
},
/* 4 */
{
"_id" : 4,
"item" : "abc",
"price" : 10,
"quantity" : 10,
"date" : ISODate("2014-02-15T08:00:00.000Z")
},
/* 5 */
{
"_id" : 5,
"item" : "xyz",
"price" : 5,
"quantity" : 10,
"date" : ISODate("2014-02-15T09:05:00.000Z")
},
/* 6 */
{
"_id" : 6,
"item" : "abc",
"price" : 10,
"quantity" : 2,
"date" : ISODate("2013-01-01T08:00:00.000Z")
},
/* 7 */
{
"_id" : 7,
"item" : "jkl",
"price" : 20,
"quantity" : 1,
"date" : ISODate("2013-02-03T09:00:00.000Z")
},
/* 8 */
{
"_id" : 8,
"item" : "xyz",
"price" : 5,
"quantity" : 5,
"date" : ISODate("2013-02-03T09:05:00.000Z")
},
/* 9 */
{
"_id" : 9,
"item" : "abc",
"price" : 10,
"quantity" : 10,
"date" : ISODate("2013-02-15T08:00:00.000Z")
},
/* 10 */
{
"_id" : 10,
"item" : "xyz",
"price" : 5,
"quantity" : 10,
"date" : ISODate("2013-02-15T09:05:00.000Z")
},
/* 11 */
{
"_id" : 11,
"item" : "abc",
"price" : 10,
"quantity" : 2,
"date" : ISODate("2012-01-01T08:00:00.000Z")
},
/* 12 */
{
"_id" : 12,
"item" : "jkl",
"price" : 20,
"quantity" : 1,
"date" : ISODate("2012-02-03T09:00:00.000Z")
},
/* 13 */
{
"_id" : 13,
"item" : "xyz",
"price" : 5,
"quantity" : 5,
"date" : ISODate("2012-02-03T09:05:00.000Z")
},
/* 14 */
{
"_id" : 14,
"item" : "abc",
"price" : 10,
"quantity" : 10,
"date" : ISODate("2012-02-15T08:00:00.000Z")
},
/* 15 */
{
"_id" : 15,
"item" : "xyz",
"price" : 5,
"quantity" : 10,
"date" : ISODate("2012-02-15T09:05:00.000Z")
},
我希望结果采用以下形式:
{
{"year": 2014}, {"minDtQuantity": 2}, {"maxDtQuantity": 10}, {"quantityDiff": 8},
{"year": 2013}, {"minDtQuantity": 2}, {"maxDtQuantity": 10}, {"quantityDiff": 8},
{"year": 2012}, {"minDtQuantity": 2}, {"maxDtQuantity": 10}, {"quantityDiff": 8},
}
对于每年,我们需要找到最小和最大日期并按年份分组,然后在这些日期找到“数量”值,然后找出每年最小和最大日期的数量之间的差异。
甚至可以使用聚合管道或mongodb中的map-reduce吗?
答案 0 :(得分:2)
这可以通过按日期排序使用聚合管道来完成,然后在按年份分组时将数量推送到数组中(使用$ year运算符从日期对象中提取年份)。那一年中最小和最大日期的数量分别是数组中的第一个和最后一个值。这些可以使用$ arrayElemAt从数组中取出。
db.collection.aggregate(
[
{
$sort: {
"date": 1
}
},
{
$group: {
"_id": { "$year": "$date" },
"quantityArray": { "$push": "$quantity" },
}
},
{
$project: {
"_id": 0,
"year": "$_id",
"minDtQuantity": { "$arrayElemAt": [ "$quantityArray", 0 ] },
"maxDtQuantity": { "$arrayElemAt": [ { "$reverseArray": "$quantityArray" }, 0 ] },
"quantityDiff": { "$subtract": [
{ "$arrayElemAt": [ { "$reverseArray": "$quantityArray" }, 0 ] },
{ "$arrayElemAt": [ "$quantityArray", 0 ] },
] }
}
},
]
);
此聚合会在您的数据上返回这些结果:
{
"year" : NumberInt(2014),
"minDtQuantity" : NumberInt(2),
"maxDtQuantity" : NumberInt(10),
"quantityDiff" : NumberInt(-8)
},
{
"year" : NumberInt(2013),
"minDtQuantity" : NumberInt(2),
"maxDtQuantity" : NumberInt(10),
"quantityDiff" : NumberInt(-8)
},
{
"year" : NumberInt(2012),
"minDtQuantity" : NumberInt(2),
"maxDtQuantity" : NumberInt(10),
"quantityDiff" : NumberInt(-8)
}
这不是您指定的格式。我不确定你需要什么,你需要在一份文件中返回的结果吗?