使用 $group 和 $lookup 进行 MongoDB 聚合

11

我想在一张表上执行"group by"操作,并与另一张表进行"join"操作。 相应的SQL语句为:

SELECT T1.total, T1.email, T1.type, table_2.name FROM
(SELECT SUM(amount) AS total, email, type 
FROM table_1
GROUP BY email, type) T1
INNER JOIN table_2
on T1.email = table_2.email 

但由于MongoDB仍然没有内联特性,所以我尝试使用"$lookup"来完成任务。以下是我的代码:

db.table_1.aggregate([
{$group : {_id : {email: "$email", type:"$type"},total: { $sum: "$amount" }}},
{$lookup: {from: "table_2", localField: "email", foreignField: "email", as: "details"}} ]);

但是在我得到的结果中,details返回了一个空对象:

{ "_id" : { "user" : "b@b.com", "type" : "Car" }, "total" : 2, "details" : [ ] }
{ "_id" : { "user" : "a@a.com", "type" : "Bike" }, "total" : 3, "details" : [ ] }
{ "_id" : { "user" : "a@a.com", "type" : "Car" }, "total" : 1, "details" : [ ] }

如果我不使用 $group 运行查询,则可以正常工作。因此,我想知道是否不能同时使用 $group 和 $lookup 函数。如果是这样,是否有解决方法或者完成查询的最佳方式是什么?

[我使用的 MongoDB 版本:> db.version() 3.2.7]

3个回答

37

我找到了解决问题的答案。我得到空数组的原因是我在$lookup里使用localField的方式不对。

由于我想将table_2与table_1的$group结果连接起来,所以本地字段应为"_id.email"。

因此,正确的查询应该是:

db.table_1.aggregate([
    {$group : {_id : {email: "$email", type:"$type"},total: { $sum: "$amount" }}},
    {$lookup: {from: "table_2", localField: "_id.email", foreignField: "email", as: "details"}},
    {$match: {details: {$ne: []}}}
]);

感谢 @Wake 和 @Clement 的帮助


没错。我没有意识到你得到了一个空数组,而本应该是匹配的电子邮件地址。 - Wake
为什么$match阶段的顺序在聚合序列的最后? - Developer

7
如果你希望你的$lookupINNER JOIN一样工作,也就是说,除非在查找表中至少有一个匹配文档,否则你不想得到任何结果,那么你可以在末尾添加一个$match,将你的查找表结果与一个空数组[ ]进行比较。
db.table_1.aggregate([
    {$group : {_id : {email: "$email", type:"$type"},total: { $sum: "$amount" }}},
    {$lookup: {from: "table_2", localField: "email", foreignField: "email", as: "details"}},
    {$match: {details: {$ne: []}}}
]);

1
这让我意识到我在数据集中混淆了外部字段和本地字段。 - Robert Dziubek

1
从Mongo 3.2版本开始,$lookup用于支持左外连接。
我想知道$group和$lookup函数是否不能一起使用。 $group和$lookup可以一起使用。
如何将其用于内部连接?
您需要添加一个条件来过滤结果。使用$match。也可以尝试使用$in。
参考资料。

https://www.mongodb.com/blog/post/joins-and-other-aggregation-enhancements-coming-in-mongodb-3-2-part-1-of-3-introduction

http://www.clusterdb.com/mongodb/joins-and-other-aggregation-enhancements-in-mongodb-3-2

https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/

https://docs.mongodb.com/manual/reference/operator/aggregation/match/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接