Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make $elemMatch (projection) return all objects that match criteria

Tags:

I will use the example from 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 },            ] } 

If I run

db.schools.find( { zipcode: 63109 },              { students: { $elemMatch: { school: 102 } } } ) 

It will give the first result of each array. Naming this:

{ "_id" : 1, "students" : [ { "name" : "john", "school" : 102, "age" : 10 } ] } { "_id" : 3 } { "_id" : 4, "students" : [ { "name" : "barney", "school" : 102, "age" : 7 } ] } 

How can I make it return all the object of the array (and not only the first) that match the criteria? Meaning this:

{  _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 }]} 
like image 399
Diolor Avatar asked Oct 31 '13 00:10

Diolor


1 Answers

In order to return multiple subdocuments, you're going to need to use the aggregation framework. This will return all of the subdocuments you're looking for:

db.zip.aggregate(   {$match: {zipcode: 63109}},   {$unwind: "$students"},   {$match: {"students.school": 102}} ) 

You can do various things to get different output, but this will return:

{     "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 } 
like image 89
EmptyArsenal Avatar answered Sep 22 '22 15:09

EmptyArsenal