2012-04-24 2 views
10

У меня есть проблема с получением информации между двумя коллекциями. Первая коллекция хранит сотрудников информация:MongoDB query IN массив объекта

{ 
     "_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", 
} 

второй информации ведомства

{ 
     "_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" 
       } 
     ] 
} 

Я пытаюсь найти: Все отделы для данного сотрудника.

Я пытался что-то вроде:

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

Но я не знаю, как я могу объяснить $ в DEPARTMENT_ID всех подразделений из сотрудников вар.

ответ

6

Это не может быть сделано с помощью простого запроса. Вам придется перебирать категории employee.departments и для каждой итерации добавить свой department_id в массив. Этот массив вы можете использовать во второй строке. Это лучше всего сделать на выбранном вами языке.

Чтобы сделать это проще, вам придется изменить свою схему. Один из вариантов: хранить информацию отдела в записи сотрудника, но в вашем случае вы будете дублировать много данных.

Я бы вместо того, чтобы предложить, чтобы каждый отдел содержит список с идентификаторами сотрудников и даты, а не как это:

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

В этом случае, вы можете просто запустить:

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

Хорошо. Да, я знаю о проблеме дизайна. Но я не делился всей информацией о отделах. На самом деле в каждом отделе есть список менеджеров (см .: post post), почему я разделял отделы и сотрудников. И вы верны в отношении цикла, но я хотел знать, можно ли это сделать с помощью простого запроса. – Kakawait

+0

Я обновил свой ответ, чтобы выполнить эту работу, вам нужно будет перепроектировать вашу схему. – Derick

1

Eсть это простой способ сделать это в Mongo 3.2, по крайней мере, всего за одну операцию:

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

$elemMatch (см. ref) помогает запросить массивное значение свойства объекта.

+0

Это выглядит великолепно, но я немного смущен. Не могли бы вы добавить документ, который вы запрашиваете для этого ответа, и прокомментировать код? Я был бы счастлив поддержать. –