在多表联合查询能力上,4.4 之前只提供了一个 $lookup stage 用于实现类似于 SQL 中的「left outer join」功能,在 4.4 中新增的 $unionWith stage 又提供了类似 SQL 中的「union all」功能,用户把两个集合中的数据聚合到一个结果集中,然后做指定的查询和过滤。区别于 $lookup stage 的是, $unionWith stage 支持分片集合。当在 Aggregate Pipeline 中使用了多个 $unionWith stage 的时候,可以对多个集合数据做聚合,使用方式如下:

{ $unionWith: { coll: "<collection>", pipeline: [ <stage1>, ... ] } }

假设我们现在有这样的数据:

db.orders_april.insertMany([
  { _id:1, item: "A", quantity: 100 },
  { _id:2, item: "B", quantity: 30 },
]);
db.orders_may.insertMany([
  { _id:1, item: "C", quantity: 20 },
  { _id:2, item: "A", quantity: 50 },
]);
db.orders_june.insertMany([
  { _id:1, item: "C", quantity: 100 },
  { _id:2, item: "D", quantity: 10 },
]);

现在我想知道orders_may,orders_june,orders_april这三个集合中,不同产品item的数量quantity总和是多少?

如果是以前,只能用代码来实现;现在可以:

db.orders_april.aggregate( [
   { $unionWith: "orders_may" },
   { $unionWith: "orders_june" },
   { $group: { _id: "$item", total: { $sum: "$quantity" } } },
   { $sort: { total: -1 }}
] )

结果:

/* 1 */
{
    "_id" : "A",
    "total" : 150.0
}

/* 2 */
{
    "_id" : "C",
    "total" : 120.0
}

/* 3 */
{
    "_id" : "B",
    "total" : 30.0
}

/* 4 */
{
    "_id" : "D",
    "total" : 10.0
}

假设我们现在有这样的数据(site:1早餐,2中餐,3晚餐;placeId:地点ID;cateringDate:时间):

在这里插入图片描述
现在我想知道每天每个地方的早餐数,中餐数,晚餐数(即在一个集合中根据条件将多条数据合并成一条进行数据统计)?

db.catering.aggregate([ 
            {
                "$unionWith" : {
                    "coll" : "catering",
                    "pipeline" : [ 
                        {
                        	//筛选条件早餐
                            "$match" : {
                                "site" : 1.0
                            }
                        }, 
                        {
                            "$addFields" : {
                                "breakfast" : 1.0,//早餐1份
                                "lunch" : 0.0,
                                "dinner" : 0.0
                            }
                        }
                    ]
                }
            }, 
            {
                "$unionWith" : {
                    "coll" : "catering",
                    "pipeline" : [ 
                        {
                        	//筛选条件中餐
                            "$match" : {
                                "site" : 2.0
                            }
                        }, 
                        {
                            "$addFields" : {
                                "breakfast" : 0.0,
                                "lunch" : 1.0,//中餐1份
                                "dinner" : 0.0
                            }
                        }
                    ]
                }
            }, 
            {
                "$unionWith" : {
                    "coll" : "catering",
                    "pipeline" : [ 
                        {
                        	//筛选条件晚餐
                            "$match" : {
                                "site" : 3.0
                            }
                        }, 
                        {
                            "$addFields" : {
                                "breakfast" : 0.0,
                                "lunch" : 0.0,
                                "dinner" : 1.0//晚餐1份
                            }
                        }
                    ]
                }
            }, 
            {
                "$addFields" : {
                	//日期格式化,因为是UTC时间所以+8小时
                    "cateringDateString" : {
                        "$dateToString" : {
                            "format" : "%Y-%m-%d",
                            "date" : "$cateringDate",
                            "timezone" : "+08:00"
                        }
                    }
                }
            }, 
            {
                "$group" : {
                	//按照日期地点分组
                    "_id" : {
                        "date" : "$cateringDateString",
                        "placeId" : "$placeId"
                    },
                    //计算所有早餐
                    "totalBreakfast" : {
                        "$sum" : "$breakfast"
                    },
                    //计算所有中餐
                    "totalLunch" : {
                        "$sum" : "$lunch"
                    },
                    //计算所有晚餐
                    "totalDinner" : {
                        "$sum" : "$dinner"
                    }
                }
            }, 
            {
                "$project" : {
                    "date" : "$_id.date",
                    "placeId" : "$_id.placeId",
                    "totalBreakfast" : 1.0,
                    "totalLunch" : 1.0,
                    "totalDinner" : 1.0,
                    "_id" : 0.0
                }
            }, 
            {
                "$sort" : {
                    "date" : 1.0
                }
            } 
            
        ])

结果:

在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐