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年起,限额仅适用于退回的文件;在流水线处理过程中,文档可能会超过这个尺寸,这对我来说是一个全新的概念。。非常感谢你