Mongodb $group by 8记录加总
我有以下收藏Mongodb $group by 8记录加总,mongodb,mongoose,mongodb-query,aggregation-framework,Mongodb,Mongoose,Mongodb Query,Aggregation Framework,我有以下收藏 { "fare" : 12, "paymentMode" : "cash", "rideType" : "Self", "userId" : ObjectId("5c25c5fa12430a348459a3d7"), "createdAt" : ISODate("2019-01-01T07:15:32.335Z") }, { "fare" : 32, "paymentMode" : "cash", "rideType"
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-01T07:15:32.335Z")
},
{
"fare" : 32,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-01T07:15:32.335Z")
},
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-02T07:15:32.335Z")
},
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-03T07:15:32.335Z")
},
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-04T07:15:32.335Z")
},
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-05T07:15:32.335Z")
},
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-06T07:15:32.335Z")
},
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-07T07:15:32.335Z")
},
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-08T08:15:32.335Z")
},
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-09T08:15:32.335Z")
}
我需要做一个聚合,将这些记录分成每8条记录的一对,还需要添加具有相同日期的记录的fare
。在上述日期,2019-01-01有两个票价
我的预期产出
{ data: [
{
"fare" : 44,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
},
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-02T07:15:32.335Z")
},
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-03T07:15:32.335Z")
},
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-04T07:15:32.335Z")
},
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-05T07:15:32.335Z")
},
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-06T07:15:32.335Z")
},
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-07T07:15:32.335Z")
},{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-08T08:15:32.335Z")
}],
data:[{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-09T08:15:32.335Z")
}
] }
如果我理解正确,您应该能够使用管道而不是常规的分组步骤。为此,您可能需要根据文档计数预先计算所需的存储桶数量。例如,如果计数为84,则bucketCount类似于
ceil(84/8)=11
。我还没有找到一种优雅的方法在相同的聚合中实现这一点
更新:
下面是一个将文档放入两个存储桶的示例
db.getCollection('probands').aggregate([
{ $sort : {'_id' : -1}}, // not necessary, but probably nice
{
$bucketAuto : {
groupBy: '$_id', // this create "groups" of one element each
buckets: 2, // calculate this value beforehand
output: {
data : {
$push : { // pushes the wanted fields into the data array
'_id': '$_id',
'fare' : '$fare',
'paymentMode' : '$paymentMode',
'createdAt' : '$createdAt',
'rideType': '$rideType',
'userId': '$userId',
}
}
}
}
},
{ $project: {_id: 0, data : 1}}
])
票价的计算是一个不同的问题,但可能比这个问题更简单,使用常规的
$group
step+$sum
您可以尝试以下聚合:
db.col.aggregate([
{
$group: {
_id: { d: { $dayOfMonth: "$createdAt" }, m: { $month: "$createdAt" }, y: { $year: "$createdAt" } },
fare: { $sum: "$fare" },
paymentMode: { $first: "$paymentMode" },
rideType: { $first: "$rideType" },
userId: { $first: "$userId" },
createdAt: { $first: "$createdAt" },
}
},
{
$sort: { createdAt: 1 }
},
{
$project: {
_id: 0
}
},
{
$group: {
_id: null,
docs: { $push: "$$ROOT" }
}
},
{
$project: {
docs: {
$map: {
input: { $range: [0, { $ceil: { $divide: [ { $size: "$docs" }, 8 ] } } ] },
as: "arrayStart",
in: {
$slice: [ "$docs", { $multiply: [ "$$arrayStart", 8 ] }, 8 ]
}
}
}
}
},
{
$unwind: "$docs"
}
])
基本上,您希望按天计算票价
,因此您需要使用日期类型和运算符来计算当天的费用。然后,您需要获得8个元素的bucket,以便将所有文档合并到单个数组中(将\u id
设置为null
)。然后,您可以简单地计算需要多少“bucket”(使用and)并将长数组转换为8元素数组。在最后一步中,您可以使用每个最终文档获得8个元素的数组。输出:
{
"_id" : null,
"docs" : [
{
"fare" : 44,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-01T07:15:32.335Z")
},
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-02T07:15:32.335Z")
},
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-03T07:15:32.335Z")
},
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-04T07:15:32.335Z")
},
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-05T07:15:32.335Z")
},
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-06T07:15:32.335Z")
},
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-07T07:15:32.335Z")
},
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-08T08:15:32.335Z")
}
]
}
{
"_id" : null,
"docs" : [
{
"fare" : 12,
"paymentMode" : "cash",
"rideType" : "Self",
"userId" : ObjectId("5c25c5fa12430a348459a3d7"),
"createdAt" : ISODate("2019-01-09T08:15:32.335Z")
}
]
}
你明白了。。。你能举个例子吗。我怎样才能做到这一点我更新了我的答案。我还意识到,
$bucketAuto
在您的用例中应该更好。太棒了!!!米克尔。。。有一个问题我可以使用$facet
而不是$push
根文档。那会更多efficient@Profer我不这么认为,$facet
允许您运行多个并行聚合管道,而$push
只是将整个文档添加到一个数组中,但是$push
在$group
阶段将整个文档放入单个数组将扩展16MB BSON限制。@教授您需要测试一下,但“限额仅适用于退回的文件;在流水线处理过程中,文件可能会超过此大小”,自2005年起,限额仅适用于退回的文件;在流水线处理过程中,文档可能会超过这个尺寸,这对我来说是一个全新的概念。。非常感谢你