que - MongoDB: ¿Cómo averiguar si un campo de matriz contiene un elemento?
mongodb español (2)
Parece que el operador $in
serviría sus propósitos perfectamente.
Podrías hacer algo como esto (pseudo-consulta):
if (db.courses.find({"students" : {"$in" : [studentId]}, "course" : courseId }).count() > 0) {
// student is enrolled in class
}
Alternativamente, puede eliminar el "course" : courseId
cláusula "course" : courseId
y obtener un conjunto de todas las clases en las que el alumno está inscrito.
Tengo dos colecciones. La primera colección contiene estudiantes:
{ "_id" : ObjectId("51780f796ec4051a536015cf"), "name" : "John" }
{ "_id" : ObjectId("51780f796ec4051a536015d0"), "name" : "Sam" }
{ "_id" : ObjectId("51780f796ec4051a536015d1"), "name" : "Chris" }
{ "_id" : ObjectId("51780f796ec4051a536015d2"), "name" : "Joe" }
La segunda colección contiene cursos:
{
"_id" : ObjectId("51780fb5c9c41825e3e21fc4"),
"name" : "CS 101",
"students" : [
ObjectId("51780f796ec4051a536015cf"),
ObjectId("51780f796ec4051a536015d0"),
ObjectId("51780f796ec4051a536015d2")
]
}
{
"_id" : ObjectId("51780fb5c9c41825e3e21fc5"),
"name" : "Literature",
"students" : [
ObjectId("51780f796ec4051a536015d0"),
ObjectId("51780f796ec4051a536015d0"),
ObjectId("51780f796ec4051a536015d2")
]
}
{
"_id" : ObjectId("51780fb5c9c41825e3e21fc6"),
"name" : "Physics",
"students" : [
ObjectId("51780f796ec4051a536015cf"),
ObjectId("51780f796ec4051a536015d0")
]
}
Cada documento del curso contiene una matriz de students
que tiene una lista de estudiantes registrados para el curso. Cuando un alumno ve un curso en una página web, necesita ver si ya se ha inscrito en el curso o no. Para hacer eso, cuando la colección de courses
sea consultada en nombre del alumno, debemos averiguar si el conjunto de students
ya contiene el ObjectId del alumno. ¿Hay alguna forma de especificar en la proyección de una consulta de búsqueda para recuperar el ObjectId
del students
matriz de students
solo si está allí?
Traté de ver si podía $ elemMatch operador pero está orientado a una serie de sub documentos. Entiendo que podría usar el framework de agregación, pero parece que sería excesivo en este caso. El marco de agregación probablemente no sea tan rápido como una sola consulta de búsqueda. ¿Hay alguna forma de consultar la recopilación de cursos para que el documento devuelto pueda tener un formato similar a este?
{
"_id" : ObjectId("51780fb5c9c41825e3e21fc4"),
"name" : "CS 101",
"students" : [
ObjectId("51780f796ec4051a536015d0"),
]
}
[ editar basado en esto ahora siendo posible en versiones recientes]
[Respuesta actualizada] Puede consultar de la siguiente manera para recuperar el nombre de la clase y la identificación del alumno solo si ya están inscriptos.
db.student.find({},
{_id:0, name:1, students:{$elemMatch:{$eq:ObjectId("51780f796ec4051a536015cf")}}})
y recibirás lo que esperabas:
{ "name" : "CS 101", "students" : [ ObjectId("51780f796ec4051a536015cf") ] }
{ "name" : "Literature" }
{ "name" : "Physics", "students" : [ ObjectId("51780f796ec4051a536015cf") ] }
[Respuesta original] No es posible hacer lo que quiere hacer actualmente. Esto es desafortunado porque usted podría hacer esto si el estudiante estaba almacenado en la matriz como un objeto. De hecho, estoy un poco sorprendido de que esté usando solo ObjectId (), ya que siempre se requerirá que busque a los estudiantes si desea mostrar una lista de los estudiantes inscritos en un curso en particular (busque la primera nombres en la colección de estudiantes: ¡dos consultas en lugar de una!)
Si estaba almacenando (como un ejemplo) un Id y un nombre en la matriz del curso de esta manera:
{
"_id" : ObjectId("51780fb5c9c41825e3e21fc6"),
"name" : "Physics",
"students" : [
{id: ObjectId("51780f796ec4051a536015cf"), name: "John"},
{id: ObjectId("51780f796ec4051a536015d0"), name: "Sam"}
]
}
Su consulta entonces sería simplemente:
db.course.find( { },
{ students :
{ $elemMatch :
{ id : ObjectId("51780f796ec4051a536015d0"),
name : "Sam"
}
}
}
);
Si ese estudiante solo estuviera inscripto en CS 101, lo recuperaría:
{ "name" : "Literature" }
{ "name" : "Physics" }
{
"name" : "CS 101",
"students" : [
{
"id" : ObjectId("51780f796ec4051a536015cf"),
"name" : "John"
}
]
}