MongoDB interroge plusieurs collections à la fois

users { "_id":"12345", "admin":1 }, { "_id":"123456789", "admin":0 } posts { "content":"Some content", "owner_id":"12345", "via":"facebook" }, { "content":"Some other content", "owner_id":"123456789", "via":"facebook" } 

Voici un extrait de mon mongodb. Je veux obtenir tous les messages qui ont “via” atsortingbut égal à “facebook” et publié par un administrateur (“admin”: 1). Je n’arrivais pas à comprendre comment acquérir cette requête. Puisque mongodb n’est pas une firebase database relationnelle, je ne pouvais pas effectuer d’opération de jointure. Quelle pourrait être la solution?

    Essayer de se joindre à MongoDB irait à l’encontre de l’objective de l’utilisation de MongoDB. Cependant, vous pouvez utiliser une DBref et écrire votre code de niveau application (ou votre bibliothèque) pour qu’il récupère automatiquement ces références pour vous.

    Ou vous pouvez modifier votre schéma et utiliser des documents incorporés .

    Votre choix final est de laisser les choses exactement comme elles sont maintenant et de faire deux requêtes.

    Voici la réponse à votre question.

     db.getCollection('users').aggregate([ {$match : {admin : 1}}, {$lookup: {from: "posts",localField: "_id",foreignField: "owner_id",as: "posts"}}, {$project : { posts : { $filter : {input : "$posts" , as : "post", cond : { $eq : ['$$post.via' , 'facebook'] } } }, admin : 1 }} ]) 

    Ou soit vous pouvez aller avec l’option de groupe mongodb.

     db.getCollection('users').aggregate([ {$match : {admin : 1}}, {$lookup: {from: "posts",localField: "_id",foreignField: "owner_id",as: "posts"}}, {$unwind : "$posts"}, {$match : {"posts.via":"facebook"}}, { $group : { _id : "$_id", posts : {$push : "$posts"} }} ]) 

    Vous pouvez utiliser $lookup (multiple) pour obtenir les enregistrements de plusieurs collections:

    Exemple:

    Si vous avez plus de collections (j’ai 3 collections pour la démonstration ici, vous pouvez en avoir plus de 3). et je veux obtenir les données de 3 collections dans un seul object:

    La collection est comme:

    db.doc1.find (). pretty ();

     { "_id" : ObjectId("5901a4c63541b7d5d3293766"), "firstName" : "shubham", "lastName" : "verma" } 

    db.doc2.find (). pretty ();

     { "_id" : ObjectId("5901a5f83541b7d5d3293768"), "userId" : ObjectId("5901a4c63541b7d5d3293766"), "address" : "Gurgaon", "mob" : "9876543211" } 

    db.doc3.find (). pretty ();

     { "_id" : ObjectId("5901b0f6d318b072ceea44fb"), "userId" : ObjectId("5901a4c63541b7d5d3293766"), "fbURLs" : "http://www.facebook.com", "twitterURLs" : "http://www.twitter.com" } 

    Maintenant, votre requête sera comme ci-dessous:

     db.doc1.aggregate([ { $match: { _id: ObjectId("5901a4c63541b7d5d3293766") } }, { $lookup: { from: "doc2", localField: "_id", foreignField: "userId", as: "address" } }, { $unwind: "$address" }, { $project: { __v: 0, "address.__v": 0, "address._id": 0, "address.userId": 0, "address.mob": 0 } }, { $lookup: { from: "doc3", localField: "_id", foreignField: "userId", as: "social" } }, { $unwind: "$social" }, { $project: { __v: 0, "social.__v": 0, "social._id": 0, "social.userId": 0 } } ]).pretty(); 

    Votre résultat sera alors:

     { "_id" : ObjectId("5901a4c63541b7d5d3293766"), "firstName" : "shubham", "lastName" : "verma", "address" : { "address" : "Gurgaon" }, "social" : { "fbURLs" : "http://www.facebook.com", "twitterURLs" : "http://www.twitter.com" } } 

    Si vous souhaitez que tous les enregistrements de chaque collection, vous devez supprimer la ligne ci-dessous de la requête:

     { $project: { __v: 0, "address.__v": 0, "address._id": 0, "address.userId": 0, "address.mob": 0 } } { $project: { "social.__v": 0, "social._id": 0, "social.userId": 0 } } 

    Après avoir supprimé le code ci-dessus, vous obtiendrez un enregistrement total en tant que:

     { "_id" : ObjectId("5901a4c63541b7d5d3293766"), "firstName" : "shubham", "lastName" : "verma", "address" : { "_id" : ObjectId("5901a5f83541b7d5d3293768"), "userId" : ObjectId("5901a4c63541b7d5d3293766"), "address" : "Gurgaon", "mob" : "9876543211" }, "social" : { "_id" : ObjectId("5901b0f6d318b072ceea44fb"), "userId" : ObjectId("5901a4c63541b7d5d3293766"), "fbURLs" : "http://www.facebook.com", "twitterURLs" : "http://www.twitter.com" } } 

    Comme mentionné précédemment dans MongoDB, vous ne pouvez pas vous joindre aux collections.

    Pour votre exemple, une solution pourrait être:

     var myCursor = db.users.find({admin:1}); var user_id = myCursor.hasNext() ? myCursor.next() : null; db.posts.find({owner_id : user_id._id}); 

    Voir le manuel de référence – section curseurs: http://es.docs.mongodb.org/manual/core/cursors/

    Une autre solution consisterait à intégrer des utilisateurs dans la collecte des publications, mais je pense que pour la plupart des applications Web, la collecte des utilisateurs doit être indépendante pour des raisons de sécurité. La collection des utilisateurs peut avoir des rôles, des permissions, etc.

     posts { "content":"Some content", "user":{"_id":"12345", "admin":1}, "via":"facebook" }, { "content":"Some other content", "user":{"_id":"123456789", "admin":0}, "via":"facebook" } 

    et alors:

     db.posts.find({user.admin: 1 }); 

    Effectuez plusieurs requêtes ou utilisez des documents incorporés ou consultez les “références de firebase database”.

    Une solution: append l’indicateur isAdmin: 0/1 à votre document de post-collecte.

    Autre solution: utiliser DBrefs

    Vous pouvez écrire un code JavaScript comme ci-dessous et appeler la fonction si nécessaire.

    Référez-vous l’illustration à: http://dbversity.com/mongodb-querying-multiple-collections-with-a-javascript/

     function colListQuery() { var tcol = new Array() tcol= db.getCollectionNames(); for(var i = 1; i < tcol.length ; i++) { query = “db.” + tcol[i] + “.find()”; var docs= eval(query); docs.forEach( function(doc, index){ print( “Database_Name:”, db, “Collection_Name:”, tcol[i], “x_value:”, doc.x, “_id:”, doc._id) }); } } 

    Ensuite, appelez-le avec colListQuery () lorsque vous en avez besoin comme indiqué dans l'illustration.