Ich möchte mit dem Aggregat mehr als zwei Sammlungen in MongoDB verbinden $lookup
. Ist es möglich mitzumachen? Gib mir einige Beispiele.
Hier habe ich drei Sammlungen:
users
::
{
"_id" : ObjectId("5684f3c454b1fd6926c324fd"),
"email" : "[email protected]",
"userId" : "AD",
"userName" : "admin"
}
userinfo
::
{
"_id" : ObjectId("56d82612b63f1c31cf906003"),
"userId" : "AD",
"phone" : "0000000000"
}
userrole
::
{
"_id" : ObjectId("56d82612b63f1c31cf906003"),
"userId" : "AD",
"role" : "admin"
}
mongodb
join
mongodb-query
Siva M.
quelle
quelle
Antworten:
Die Join-Funktion, die von Mongodb 3.2 und höheren Versionen unterstützt wird. Sie können Joins verwenden, indem Sie eine aggregierte Abfrage verwenden.
Sie können dies anhand des folgenden Beispiels tun:
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", } } ]);
Dies ergibt ein Ergebnis wie folgt:
{ "_id" : ObjectId("5684f3c454b1fd6926c324fd"), "email" : "[email protected]", "userName" : "admin", "userPhone" : "0000000000", "role" : "admin" }
Hoffe das wird dir oder jemand anderem helfen.
Vielen Dank
quelle
Sie können tatsächlich mehrere $ Lookup-Stufen verketten. Basierend auf den Namen der von profesor79 freigegebenen Sammlungen können Sie Folgendes tun:
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" } ])
Dies gibt die folgende Struktur zurück:
{ "_id" : ObjectId("56d82612b63f1c31cf906003"), "userId" : "AD", "phone" : "0000000000", "userRole" : { "_id" : ObjectId("56d82612b63f1c31cf906003"), "userId" : "AD", "role" : "admin" }, "userInfo" : { "_id" : ObjectId("56d82612b63f1c31cf906003"), "userId" : "AD", "phone" : "0000000000" } }
Vielleicht könnte dies als Anti-Muster angesehen werden, da MongoDB nicht als relational gedacht war, aber es ist nützlich.
quelle
Gemäß der Dokumentation kann $ lookup nur einer externen Sammlung beitreten.
Was Sie tun können, ist zu kombinieren
userInfo
unduserRole
in einer Sammlung, wie angegeben, basiert das Beispiel auf einem relationalen DB-Schema. Mongo ist eine noSQL-Datenbank - und dies erfordert einen anderen Ansatz für die Dokumentenverwaltung.Im Folgenden finden Sie eine zweistufige Abfrage, die userInfo mit userRole kombiniert und eine neue temporäre Sammlung erstellt, die in der letzten Abfrage zum Anzeigen kombinierter Daten verwendet wird. In der letzten Abfrage besteht die Möglichkeit, $ out zu verwenden und eine neue Sammlung mit zusammengeführten Daten für die spätere Verwendung zu erstellen.
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" } } ])
quelle
$lookup can join only one external collection
? Ich habe keine Einschränkung im Dokumentlink gefunden. DankeIch verstehe nicht, warum Sie eine Beziehung zur Benutzer-ID haben, warum Sie die Objekt-ID nicht verwenden, um beide Dokumente zu verknüpfen. Grüße.
quelle
Fügen Sie zuerst die Sammlungen hinzu und wenden Sie dann eine Suche auf diese Sammlungen an. Nicht
$unwind
zum Abwickeln verwenden, werden einfach alle Dokumente der einzelnen Sammlungen getrennt. Wenden Sie also eine einfache Suche an und verwenden Sie sie dann$project
für die Projektion. Hier ist mongoDB Abfrage:db.userInfo.aggregate([ { $lookup: { from: "userRole", localField: "userId", foreignField: "userId", as: "userRole" } }, { $lookup: { from: "userInfo", localField: "userId", foreignField: "userId", as: "userInfo" } }, {$project: { "_id":0, "userRole._id":0, "userInfo._id":0 } } ])
Hier ist die Ausgabe:
/* 1 */ { "userId" : "AD", "phone" : "0000000000", "userRole" : [ { "userId" : "AD", "role" : "admin" } ], "userInfo" : [ { "userId" : "AD", "phone" : "0000000000" } ] }
Vielen Dank.
quelle