web-dev-qa-db-ja.com

$ groupと$ lookupを使用したmongodbアグリゲート

テーブルに対して「groupby」を実行し、別のテーブルと「結合」しようとしています。対応する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"}} ]);

しかし、私が得ている結果では、詳細が返され、オブジェクトは空になります。

{ "_id" : { "user" : "[email protected]", "type" : "Car" }, "total" : 2, "details" : [ ] }
{ "_id" : { "user" : "[email protected]", "type" : "Bike" }, "total" : 3, "details" : [ ] }
{ "_id" : { "user" : "[email protected]", "type" : "Car" }, "total" : 1, "details" : [ ] }

しかし、$ groupを使用せずにクエリを実行すると、正常に機能します。したがって、$ group関数と$ lookup関数を一緒に使用できないかどうか疑問に思っています。もしそうなら、回避策はありますか、それともクエリを実行するための最適な方法は何でしょうか?

[私が使用しているmongodbバージョン:> db.version()3.2.7]

5
KTB

私はその問題に対する答えを見つけました。空の配列を取得した理由は、$ 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に助けてくれてありがとう

23
KTB

$ lookupINNER JOINのように機能させたい場合、つまり、ルックアップテーブルに一致するドキュメントが少なくとも1つない限り、結果は必要ありません。ルックアップテーブルの結果を空の配列と比較する最後に$ 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: []}}}
]);
5
Wake

Mongoバージョン3.2以降では、$ lookupは左外部結合をサポートするために使用されます。

$ group関数と$ lookup関数を一緒に使用できないかどうか疑問に思っています。

$ groupと$ lookupは一緒に使用できます。

内部結合に使用する方法

結果をフィルタリングするための条件をもう1つ追加しました。 $ 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/

1