objects - mongodb query subdocument array
Make $ elemMatch(proyección) devuelve todos los objetos que coinciden con los criterios (2)
Para devolver varios subdocumentos, deberá usar el marco de agregación. Esto devolverá todos los subdocumentos que está buscando:
db.zip.aggregate(
{$match: {zipcode: 63109}},
{$unwind: "$students"},
{$match: {"students.school": 102}}
)
Puedes hacer varias cosas para obtener una salida diferente, pero esto devolverá:
{
"result" : [
{
"_id" : 1,
"zipcode" : 63109,
"students" : {
"name" : "john",
"school" : 102,
"age" : 10
}
},
{
"_id" : 1,
"zipcode" : 63109,
"students" : {
"name" : "jess",
"school" : 102,
"age" : 11
}
},
{
"_id" : 4,
"zipcode" : 63109,
"students" : {
"name" : "barney",
"school" : 102,
"age" : 7
}
}
],
"ok" : 1
}
Usaré el ejemplo de here
{
_id: 1,
zipcode: 63109,
students: [
{ name: "john", school: 102, age: 10 },
{ name: "jess", school: 102, age: 11 },
{ name: "jeff", school: 108, age: 15 }
]
}
{
_id: 2,
zipcode: 63110,
students: [
{ name: "ajax", school: 100, age: 7 },
{ name: "achilles", school: 100, age: 8 },
]
}
{
_id: 3,
zipcode: 63109,
students: [
{ name: "ajax", school: 100, age: 7 },
{ name: "achilles", school: 100, age: 8 },
]
}
{
_id: 4,
zipcode: 63109,
students: [
{ name: "barney", school: 102, age: 7 },
]
}
Si corro
db.schools.find( { zipcode: 63109 },
{ students: { $elemMatch: { school: 102 } } } )
Se dará el primer resultado de cada matriz. Nombrando esto:
{ "_id" : 1, "students" : [ { "name" : "john", "school" : 102, "age" : 10 } ] }
{ "_id" : 3 }
{ "_id" : 4, "students" : [ { "name" : "barney", "school" : 102, "age" : 7 } ] }
¿Cómo puedo hacer que devuelva todo el objeto de la matriz (y no solo el primero) que coincida con los criterios? Lo que significa esto:
{
_id: 1,
students: [
{ name: "john", school: 102, age: 10 },
{ name: "jess", school: 102, age: 11 }
]
}
{ _id: 3 }
{_id: 4, students: [ { name: "barney", school: 102, age: 7 }]}
Respuesta anterior e incorrecta:
Esto debería funcionar a partir de hoy. Consulte https://docs.mongodb.com/v3.2/reference/operator/projection/positional/#array-field-limitations
Debería obtener el resultado correcto al consultar con $elemMatch
en la consulta y exponer el sub-documento en la proyección como sigue:
db.schools.find( { zipcode: 63109, students: { $elemMatch: { school: 102 } } },
{ ''students.$'': 1 } )
Nueva respuesta
Limitar la lista de sub-documentos a aquellos que coinciden con la consulta no es posible a partir de ahora utilizando find()
. Por favor, tome aggregate()
lugar o tome una de las siguientes posibilidades:
También puede obtener todos los documentos secundarios del documento correspondiente agregando la propiedad de matriz en la proyección:
db.schools.find( { zipcode: 63109, students: { $elemMatch: { school: 102 } } }, { ''students'': 1 })
> { "_id" : 1, "students" : [ { "name" : "john", "school" : 102, "age" : 10 }, { "name" : "jess", "school" : 102, "age" : 11 }, { "name" : "jeff", "school" : 108, "age" : 15 } ] }
> { "_id" : 4, "students" : [ { "name" : "barney", "school" : 102, "age" : 7 } ] }
O puede obtener el primer elemento que coincida con la consulta $elemMatch
en los documentos secundarios:
db.schools.find( { zipcode: 63109, students: { $elemMatch: { school: 102 } } }, { ''students.$'': 1 })
> { "_id" : 1, "students" : [ { "name" : "john", "school" : 102, "age" : 10 } ] }
> { "_id" : 4, "students" : [ { "name" : "barney", "school" : 102, "age" : 7 } ] }