2012-04-24 24 views
10

Tengo un problema para recuperar información entre dos colecciones. La primera almacenes de la colección empleados información:Consulta de MongoDB EN matriz del objeto

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

el segundo la información departamentos

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

trato de encontrar: Todos los departamentos para un empleado determinado.

he intentado algo así como:

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

Pero no sé cómo puedo explicar en $ department_id de todos los departamentos de los empleados var.

Respuesta

6

Esto no se puede hacer con una simple consulta. Deberá pasar por encima de los departamentos de los empleados y para cada iteración agregar su department_id a una matriz. Esta matriz puede usar en su segunda línea. Esto es algo que se hace mejor en el idioma de su elección.

Para hacerlo más fácil, tendrá que cambiar su esquema. Una opción es almacenar la información del departamento en el registro del empleado, pero en su caso estaría duplicando una gran cantidad de datos.

En vez de ello sugeriría que cada departamento contiene una lista con los ID de los empleados y las fechas de su lugar como este:

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

En ese caso, puede entonces simplemente ejecuta:

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

Ok .. Sí, sé sobre el problema de diseño. Pero no compartí toda la información sobre los departamentos. De hecho, cada departamento tiene una lista de gerentes (ver: publicar actualización) que explica por qué dividí los departamentos y los empleados. Y usted es sincero con respecto al bucle, pero quería saber si es posible hacerlo con la consulta simple – Kakawait

+0

He actualizado mi respuesta, para que esto funcione, tendrá que rediseñar su esquema. – Derick

1

Hay una manera fácil de hacerlo en Mongo 3.2, al menos en una sola operación:

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

The 012 El modificador(ver ref) ayuda a consultar contra un valor similar a una matriz de una propiedad de objeto.

+0

Esto se ve genial, pero estoy un poco confundido. ¿Podría agregar el documento que está consultando a esta respuesta y comentar el código? Estaría feliz de haber votado positivamente. –

Cuestiones relacionadas