Запрос объекта MongoDB IN array of object

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

{
        "_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 всех отделов от сотрудников var.

Ответ 1

Это невозможно сделать с помощью простого запроса. Вам придется перебирать категории 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") } );

Ответ 2

Есть простой способ сделать это в 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) помогает запросить массивное значение свойства объекта.