如何在不使用 $facet 的情况下组合两个 MongoDB 聚合管道查询的结果并对组合结果执行另一个聚合查询?

How to combine results of two MongoDB aggregation pipeline queries and perform another aggregation query on the combined result without using $facet?

我的第一个查询 returns 以下结果,经过各种聚合管道阶段:

{ 
    "group" : "A",
    "count" : 6, 
    "total" : 20
},
{
    "group" : "B",
    "count" : 2,
    "total" : 50
}

我的第二个查询 returns 以下结果,经过各种聚合管道阶段:

{
    "group": "A",
    "count": 4,
    "total": 80
},
{
    "group": "C",
    "count": 12,
    "total": 60
}

Both the queries are performed on the same collection, but groups and transforms the data differently based on the pipeline stages.

Both of my queries use different $match conditions, have various pipeline stages including $facet,$unwind,$group,$project and operators like $map,$reduce,$zip,$subtract...

db.collection.aggregate([
{ $unwind...},
{ $match....},
{ $facet...},
...
])

当我使用 $facet 到 运行 我的查询作为并行查询时,它给出了以下错误(因为我已经在我现有的查询中使用 $facet ):

$facet is not allowed to be used within a $facet stage

预期输出:

I need to find the average value for each of the group.

为此,我需要合并两个查询的结果并对合并结果执行查询。

我的组合舞台应该是这样的:

{ 
    "group" : "A",
    "count" : 10, 
    "total" : 100 
},
{
    "group" : "B",
    "count" : 2,
    "total" : 50
},
{
    "group": "C",
    "count": 12,
    "total": 60
}

每组的预期最终结果和平均值:

{
    "group" : "A",
     "avg" : 10 
},
{
    "group" : "B",
    "avg" : 25
},
{
    "group": "C",
    "avg": 5
}

MongoDB 聚合管道中是否有可用的运算符来实现此目的而无需修改我现有的查询?

如何实现这个用例?

谢谢!

您可以 运行 使用 $facet 单独查询,然后使用以下转换将 $group 组合结果 group 并计算平均值:

db.collection.aggregate([
    {
        $facet: {
            first: [ { $match: { "_": true } } ], // your first query
            second: [ { $match: { "_": false } } ], // your second query
        }
    },
    {
        $project: {
            all: {
                $concatArrays: [ "$first", "$second" ]
            }
        }
    },
    {
        $unwind: "$all"
    },
    {
        $group: {
            _id: "$all.group",
            count: { $sum: "$all.count" },
            total: { $sum: "$all.total" },
        }
    },
    {
        $project: {
            _id: 0,
            group: "$_id",
            count: 1,
            total: 1,
            avg: { $divide: [ "$total", "$count" ] }
        }
    }
])

Mongo Playground

注意:我使用 _ 字符来指示文档来自哪个查询。显然你不需要它,你可以用你自己的

替换 $facet 查询

合并结果的方法有多种,包括在 4.2

中引入的 $merge

但是我用的是4.0以后的方法

将两个聚合查询结果保存在一个变量中,然后将其插入到一个新的临时集合中:

var result  = db.collection.aggregate(...); //query1 here
db.temp.insert(result.toArray());

var result  = db.collection.aggregate(...); //query2 here
db.temp.insert(result.toArray());

// Find out average
db.temp.aggregate([
    {
        $group: {
            _id: "$group",
            count: { $sum: "$count" },
            total: { $sum: "$total" }
        }
    },
    {
        $project: {
            _id: 0,
            group: "$_id",
            avg: { $divide: [ "$total", "$count" ] }
        }
    }
]).pretty()