OPTIONS

$elemMatch (projection)

$elemMatch

New in version 2.2.

The $elemMatch projection operator limits the contents of an array field that is included in the query results to contain only the array element that matches the $elemMatch condition.

Note

  • The elements of the array are documents.
  • If multiple elements match the $elemMatch condition, the operator returns the first matching element in the array.
  • The $elemMatch projection operator is similar to the positional $ projection operator.

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 },
           ]
}

Example

The following find() operation queries for all documents where the value of the zipcode field is 63109. The $elemMatch projection returns only the first matching element of the students array where the school field has a value of 102:

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

The operation returns the following documents:

{ "_id" : 1, "students" : [ { "name" : "john", "school" : 102, "age" : 10 } ] }
{ "_id" : 3 }
{ "_id" : 4, "students" : [ { "name" : "barney", "school" : 102, "age" : 7 } ] }
  • For the document with _id equal to 1, the students array contains multiple elements with the school field equal to 102. However, the $elemMatch projection returns only the first matching element from the array.
  • The document with _id equal to 3 does not contain the students field in the result since no element in its students array matched the $elemMatch condition.

The $elemMatch projection can specify criteria on multiple fields:

Example

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 }

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

When the find() method includes a sort(), the find() method applies the sort() to order the matching documents before it applies the 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.

Example

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" : 1, "students" : [ { "name" : "john", "school" : 102, "age" : 10 } ] }
{ "_id" : 3 }
{ "_id" : 4, "students" : [ { "name" : "barney", "school" : 102, "age" : 7 } ] }

See also

$ (projection) operator

←   $ (projection) $meta  →