2016-03-05 52 views
23

我想使用集合$ lookup加入兩個以上的集合。有可能加入嗎?請告訴我是否有可能。給我舉個例子。在這裏,我有三個類別:

「用戶」

{  
"_id" : ObjectId("5684f3c454b1fd6926c324fd"), 
    "email" : "[email protected]", 
    "userId" : "AD", 
    "userName" : "admin" 
} 

「用戶信息」

{ 
    "_id" : ObjectId("56d82612b63f1c31cf906003"), 
    "userId" : "AD", 
    "phone" : "0000000000" 
} 

「的UserRole」

{ 
    "_id" : ObjectId("56d82612b63f1c31cf906003"), 
    "userId" : "AD", 
    "role" : "admin" 
} 
+0

的[多加入使用$查找操作條件]可能的複製(https://stackoverflow.com/questions/37086387/multiple-join-conditions-using-the-lookup-operator) – styvane

+0

可能[如何查詢MongoDB中的引用對象?](https:// stackoverflow。com/questions/9621928/how-do-i-query-referenced-objects-in-mongodb) – sidgate

回答

9

按照documentation,$查找只能加入一個外部集合。

您可以做的是將userInfouserRole合併到一個集合中,因爲所提供的示例基於關係數據庫架構。 Mongo是NoSQL數據庫 - 這需要不同的文件管理方法。

請在下面找到兩步查詢,它將userInfo和userRole結合起來 - 創建用於上次查詢的新臨時集合以顯示組合數據。 在上次查詢中,有一個選項可以使用$ out並使用合併數據創建新集合以備將來使用。

創建集合

db.sivaUser.insert(
{  
    "_id" : ObjectId("5684f3c454b1fd6926c324fd"), 
     "email" : "[email protected]", 
     "userId" : "AD", 
     "userName" : "admin" 
}) 

//"userinfo" 
db.sivaUserInfo.insert(
{ 
    "_id" : ObjectId("56d82612b63f1c31cf906003"), 
    "userId" : "AD", 
    "phone" : "0000000000" 
}) 

//"userrole" 
db.sivaUserRole.insert(
{ 
    "_id" : ObjectId("56d82612b63f1c31cf906003"), 
    "userId" : "AD", 
    "role" : "admin" 
}) 

「加盟」 他們都:-)

db.sivaUserInfo.aggregate([ 
    {$lookup: 
     { 
      from: "sivaUserRole", 
      localField: "userId", 
      foreignField: "userId", 
      as: "userRole" 
     } 
    }, 
    { 
     $unwind:"$userRole" 
    }, 
    { 
     $project:{ 
      "_id":1, 
      "userId" : 1, 
      "phone" : 1, 
      "role" :"$userRole.role" 
     } 
    }, 
    { 
     $out:"sivaUserTmp" 
    } 
]) 


db.sivaUserTmp.aggregate([ 
    {$lookup: 
     { 
      from: "sivaUser", 
      localField: "userId", 
      foreignField: "userId", 
      as: "user" 
     } 
    }, 
    { 
     $unwind:"$user" 
    }, 
    { 
     $project:{ 
      "_id":1, 
      "userId" : 1, 
      "phone" : 1, 
      "role" :1, 
      "email" : "$user.email", 
      "userName" : "$user.userName" 
     } 
    } 
]) 
+0

hmmm ........... –

+0

有趣...性能測試? –

22

實際上,你可以串聯多個$查找階段。基於由profesor79共享的集合名稱,你可以這樣做:

db.sivaUserInfo.aggregate([ 
    { 
     $lookup: { 
      from: "sivaUserRole", 
      localField: "userId", 
      foreignField: "userId", 
      as: "userRole" 
     } 
    }, 
    { 
     $unwind: "$userRole" 
    }, 
    { 
     $lookup: { 
      from: "sivaUserInfo", 
      localField: "userId", 
      foreignField: "userId", 
      as: "userInfo" 
     } 
    }, 
    { 
     $unwind: "$userInfo" 
    } 
]) 

這將返回以下結構:

{ 
    "_id" : ObjectId("56d82612b63f1c31cf906003"), 
    "userId" : "AD", 
    "phone" : "0000000000", 
    "userRole" : { 
     "_id" : ObjectId("56d82612b63f1c31cf906003"), 
     "userId" : "AD", 
     "role" : "admin" 
    }, 
    "userInfo" : { 
     "_id" : ObjectId("56d82612b63f1c31cf906003"), 
     "userId" : "AD", 
     "phone" : "0000000000" 
    } 
} 

也許這可以被認爲是一個反模式,因爲MongoDB的WASN」 t意味着關係,但它是有用的。

+2

這確實有效。謝謝! –

+0

如果我們想在用戶角色中顯示userinfo作爲arry,該怎麼辦?如何做到這一點 –

16

Mongodb 3.2及更高版本支持的加入功能。您可以使用聚合查詢來使用連接。
您可以通過下面的例子做:

db.users.aggregate([ 

    // Join with user_info table 
    { 
     $lookup:{ 
      from: "userinfo",  // other table name 
      localField: "userId", // name of users table field 
      foreignField: "userId", // name of userinfo table field 
      as: "user_info"   // alias for userinfo table 
     } 
    }, 
    { $unwind:"$user_info" },  // $unwind used for getting data in object or for one record only 

    // Join with user_role table 
    { 
     $lookup:{ 
      from: "userrole", 
      localField: "userId", 
      foreignField: "userId", 
      as: "user_role" 
     } 
    }, 
    { $unwind:"$user_role" }, 

    // define some conditions here 
    { 
     $match:{ 
      $and:[{"userName" : "admin"}] 
     } 
    }, 

    // define which fields are you want to fetch 
    { 
     $project:{ 
      _id : 1, 
      email : 1, 
      userName : 1, 
      userPhone : "$user_info.phone", 
      role : "$user_role.role", 
     } 
    } 
]); 

這會給結果是這樣的:

{ 
    "_id" : ObjectId("5684f3c454b1fd6926c324fd"), 
    "email" : "[email protected]", 
    "userName" : "admin", 
    "userPhone" : "0000000000", 
    "role" : "admin" 
} 

希望這將幫助你或其他人。

感謝

+0

如果你想從其他表中取出數據而不是從表中刪除** $ unwind **就意味着從查詢中取出「** {$ unwind:」$ user_role「} **」來自** user_role **表的數組 –