web-dev-qa-db-fra.com

Comment faire la jointure interne dans MongoDB?

Est-il possible de faire du genre de jointures internes SQL dans MongoDB, eh bien je sais qu'il y a

$ recherche

attribut dans le pipeline d'agrégation et il est équivalent aux jointures externes dans SQL mais je veux faire un genre de tâche similaire à celui des jointures internes, j'ai deux trois collections, que j'ai besoin de fusionner ensemble

----User Collection----
db.User.find({})
{
   ID : 1,
   USER_NAME : "John",
   password : "pass"
}
{

   ID : 2,
   USER_NAME : "Andrew",
   PASSWORD : "andrew"
}

---ROLE COLLECTION---
db.ROLE.find({})
{
   ID : 1,
   ROLE_NAME : "admin"
},
{
    ID : 2,
    ROLE_NAME : "staff"
}

---USER_ROLE COLLECTION---
db.USER_ROLE.find({})
{
   ID : 1,
   USER_ID : 1,
   ROLE_ID : 1
}

j'ai plus de 3 collections et je veux extraire uniquement les documents correspondant aux utilisateurs et leurs rôles respectifs pas tous les documents, comment puis-je le gérer dans MongoDB quelqu'un peut-il me donner une suggestion?

8
Asantha Thilina

Comme l'écrivait Tiramisu, cela ressemble à un problème de schéma.

Vous pouvez créer une jointure interne manuelle en supprimant les documents où $ lookup a renvoyé un tableau vide.

....
{$lookup... as myArray},
{$match: {"myArray":{$ne:[]}}},
{$lookup... as myArray2},
{$match: {"myArray2":{$ne:[]}}},

changement de schéma

Personnellement, j'irai pour la mise à jour du schéma, comme ceci:

db.User.find({})
{
   ID : 1,
   USER_NAME : "John",
   password : "pass"
   roles:[{ID : 1,  ROLE_NAME : "admin"}]
}


db.ROLE.find({})
{
   ID : 1,
   ROLE_NAME : "admin"
},
11
profesor79

J'ai trouvé ma réponse c'était

$ dérouler m'a fait l'affaire après que la requête ait fonctionné pour moi

    db.USER.aggregate([{
            $lookup: {
                from: "USER_ROLE",
                localField: "ID",
                foreignField: "USER_ID",
                as: "userRole"
            }
        }, {
            $unwind: {
                path: "$userRole",
                preserveNullAndEmptyArrays: false
            }
        }, {
            $lookup: {
                from: "ROLE",
                localField: "userRole.ROLE_ID",
                foreignField: "ID",
                as: "role"
            }
        }, {
            $unwind: {
                path: "$role",
                preserveNullAndEmptyArrays: false
            }
        }, {
            $match: {
                "role.ROLE_NAME": "staff"
            }, {
                $project: {
                    USER_NAME: 1,
                    _id: 0
                }
            }
            ]).pretty()

Merci pour les réponses

13
Asantha Thilina

Est-ce que cela va aider

const RolesSchema = new Schema({
  ....

});
const Roles = mongoose.model('Roles', RolesSchema);


const UserSchema = new Schema({
  ...

  roles: [{ type: mongoose.Schema.Types.ObjectId, ref: "Roles" }]
});

en utilisant le remplir sur le schéma des utilisateurs, vous pouvez également réduire la redondance

0
skyhavoc