如何编写自我加入查询

时间:2017-06-17 10:39:33

标签: mongodb aggregation-framework

我有简单的收藏transactions,其中包含用户和餐馆的信息

{ "user_id" : "U1", "restaurant_id" : "R_1" }
{ "user_id" : "U2", "restaurant_id" : "R_1" }
{ "user_id" : "U1", "restaurant_id" : "R_3" }
{ "user_id" : "U1", "restaurant_id" : "R_4" }
{ "user_id" : "U2", "restaurant_id" : "R_4" }

在这里,我需要找到具有user_id U1 U2 的用户之间的相关餐厅(即我想找到那些 U1 和<的餐厅强> U2 都参观过了)

我应该收到这样的输出: -

{ "_id" : "R_4", "users" : [ "U2", "U1" ] }
{ "_id" : "R_1", "users" : [ "U2", "U1" ] }

用户 U1 U2

访问了 R_1 R_4 餐厅

我是mongoDb的新用户,所以在google搜索后我编写的样本查询无法正常工作

db.transactions.aggregate([
    {$match: {"user_id": {
        "$in": [ U1, U2]
    }}},
    {
        $lookup: {
           from: "transactions",
           localField: "restaurant_id",
           foreignField: "restaurant_id",
           as: "related_taste"
         }
    }
])

1 个答案:

答案 0 :(得分:3)

你想要的是结果的“联合”,如下所示:

db.transactions.aggregate([
    { "$match": { "user_id": { "$in": [ "U1", "U2" ] } }},
    { "$group": {
      "_id": "$restaurant_id",
      "users": { "$addToSet": "$user_id" }
    }},
    { "$match": { "users": { "$all": [ "U1", "U2" ] } } }
])

给出了输出:

{ "_id" : "R_4", "users" : [ "U2", "U1" ] }
{ "_id" : "R_1", "users" : [ "U2", "U1" ] }

这是如何工作的,$group阶段累积在restaurant_id值上,并通过该user_id值的$addToSet保留“设置”键。

然后我们$match再次使用$all条件查看我们收集“set”的餐馆中提供的“两个”所提供的user_id值。

因此,只有“一个”列出的用户访问过的任何地方都会被丢弃,我们会得到两者都访问过的结果。

对您的数据进行更正:

{ "user_id" : "U1", "restaurant_id" : "R_1" }
{ "user_id" : "U2", "restaurant_id" : "R_1" }
{ "user_id" : "U1", "restaurant_id" : "R_3" }
{ "user_id" : "U1", "restaurant_id" : "R_4" }
{ "user_id" : "U2", "restaurant_id" : "R_4" }