2012-04-24 1 views
10

J'ai un problème pour récupérer des informations entre deux collections. Le premier magasin de collecte des informations sur les employés:requête MongoDB dans le tableau de l'objet

{ 
     "_id" : ObjectId("4f9643967f8b9a3f0a00005a"), 
     "birth_date" : "1963-09-09", 
     "departments" : [ 
       { 
         "departments_id" : ObjectId("4f9643957f8b9a3f0a000007"), 
         "from_date" : "1990-01-03", 
         "to_date" : "1990-01-15" 
       } 
     ], 
     "first_name" : "Parviz", 
     "gender" : "M", 
     "hire_date" : "1990-01-03", 
     "last_name" : "Lortz", 
} 

le second les départements informations

{ 
     "_id" : ObjectId("4f9643957f8b9a3f0a000004"), 
     "dept_name" : "Marketing", 
     "managers" : [ 
       { 
         "employees_id" : ObjectId("4f96439b7f8b9a3f0a0186a9"), 
         "from_date" : "1985-01-01", 
         "to_date" : "1991-10-01" 
       }, 
       { 
         "employees_id" : ObjectId("4f96439b7f8b9a3f0a0186aa"), 
         "from_date" : "1991-10-01", 
         "to_date" : "9999-01-01" 
       } 
     ] 
} 

J'essaie de trouver: Tous les départements pour un employé donné.

J'ai essayé quelque chose comme:

employees = db.employees.find({_id:ObjectId("some_id")}); 
db.departments.find({_id:{$in:...}}); 

Mais je ne sais pas comment je peux expliquer $ en department_id de tous les services des employés var.

Répondre

6

Cela ne peut pas être fait avec une simple requête. Vous devrez faire une boucle sur les employés.departments et pour chaque itération ajoutez son department_id à un tableau. Ce tableau que vous pouvez ensuite utiliser dans votre deuxième ligne. C'est quelque chose de mieux fait dans la langue de votre choix. Pour faciliter cela, vous devrez modifier votre schéma. Une option consiste à stocker les informations de département dans l'enregistrement d'employé, mais dans votre cas, vous dupliqueriez beaucoup de données.

Je place suggérer que chaque ministère contient une liste au lieu ID employé et dates comme celle-ci:

{ 
     "_id" : ObjectId("4f9643957f8b9a3f0a000004"), 
     "dept_name" : "Marketing", 
     "managers" : [ 
     ] 
     "employees" : [ 
      { 
        "employee_id" : ObjectId("4f9643967f8b9a3f0a00005a"), 
        "from_date" : "1990-01-03", 
        "to_date" : "1990-01-15" 
      } 
     ] 
} 

Dans ce cas, vous pouvez exécuter simplement:

db.departments.find({ "employees.employee_id": ObjectId("some_id") }); 
+0

Ok .. Oui, je connais le problème de conception. Mais je n'ai pas partagé toutes les informations sur les départements. En effet, chaque département dispose d'une liste de managers (voir: mise à jour post), c'est pourquoi j'ai divisé les départements et les employés. Et vous avez la vérité sur la boucle, mais je voulais savoir s'il est possible de le faire avec une simple requête – Kakawait

+0

J'ai mis à jour ma réponse, pour que cela fonctionne, vous devrez refaire votre schéma. – Derick

1

Il est un moyen facile de le faire à Mongo 3.2, au moins en seulement une seule opération:

const employees = db.employees.find(); // query the employees collection 
db.departments.find({ 
    managers: { 
    $elemMatch: { 
     employees_id: { 
     $in: employees.map(e => e._id) 
     } 
    } 
    } 
}); 

012 Modificateur(voir ref) aide à la requête par rapport à une valeur de type tableau d'une propriété d'objet.

+0

Cela semble très bien, mais je suis un peu confus. Pourriez-vous ajouter le document que vous interrogez à cette réponse et commenter le code? Je serais heureux d'upvote. –

Questions connexes