Navigation
This version of the documentation is archived and no longer supported.

$elemMatch (projection)

Definition

$elemMatch

New in version 2.2.

The $elemMatch operator limits the contents of an <array> field from the query results to contain only the first element matching the $elemMatch condition.

Usage Considerations

Both the $ operator and the $elemMatch operator project a subset of elements from an array based on a condition.

The $ operator projects the array elements based on some condition from the query statement.

The $elemMatch projection operator takes an explicit condition argument. This allows you to project based on a condition not in the query, or if you need to project based on multiple fields in the array’s subdocuments. See Array Field Limitations for an example.

Examples

The examples on the $elemMatch projection operator assumes a collection school with the following documents:

{
 _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 },
              { name: "ruth", school: 102, age: 16 },
           ]
}

$elemMatch with Multiple Fields

The $elemMatch projection can specify criteria on multiple fields:

The following find() operation queries for all documents where the value of the zipcode field is 63109. The projection includes the first matching element of the students array where the school field has a value of 102 and the age field is greater than 10:

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

The operation returns the three documents that have zipcode equal to 63109:

{ "_id" : 1, "students" : [ { "name" : "jess", "school" : 102, "age" : 11 } ] }
{ "_id" : 3 }
{ "_id" : 4, "students" : [ { "name" : "ruth", "school" : 102, "age" : 16 } ] }

Documents with _id equal to 3 and _id equal to 4 do not contain the students field since no array element matched the $elemMatch criteria.

$elemMatch with sort()

When the find() method includes a sort(), the find() method applies the sort() to order the matching documents before it applies the projection. This is a general rule when sorting and projecting, and is discussed in Interaction with Projection.

If an array field contains multiple documents with the same field name and the find() method includes a sort() on that repeating field, the returned documents may not reflect the sort order because the sort() was applied to the elements of the array before the $elemMatch projection.

An array’s sorting value is taken from either its “minimum” or “maximum” value, depending on which way the sorting goes. The way that sort() sorts documents containing arrays is described in Sort Order.

The following query includes a sort() to order by descending students.age field:

db.schools.find(
                 { zipcode: "63109" },
                 { students: { $elemMatch: { school: 102 } } }
               ).sort( { "students.age": -1 } )

The operation applies the sort() to order the documents that have the field zipcode equal to 63109 and then applies the projection. The operation returns the three documents in the following order:

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

Even though the sort is descending, the younger student is listed first. This is because the sort occured before the older students in Barney’s document were projected out.

See also

$ (projection) operator