OPTIONS

$ (projection)

Definition

$

The positional $ operator limits the contents of the <array> field that is included in the query results to contain the first matching element. To specify an array element to update, see the positional $ operator for updates.

Used in the projection document of the find() method or the findOne() method:

  • The $ projection operator limits the content of the <array> field to the first element that matches the query document.

  • The <array> field must appear in the query document

    db.collection.find( { <array>: <value> ... },
                        { "<array>.$": 1 } )
    db.collection.find( { <array.field>: <value> ...},
                        { "<array>.$": 1 } )
    

    The <value> can be documents that contains query operator expressions.

  • Only one positional $ operator can appear in the projection document.

  • Only one array field can appear in the query document; i.e. the following query is incorrect:

    db.collection.find( { <array>: <value>, <someOtherArray>: <value2> },
                        { "<array>.$": 1 } )
    

Behavior

Array Field Limitation

Since only one array field can appear in the query document, if the array contains documents, to specify criteria on multiple fields of these documents, use the $elemMatch operator. For example:

db.students.find( { grades: { $elemMatch: {
                                            mean: { $gt: 70 },
                                            grade: { $gt:90 }
                                          } } },
                  { "grades.$": 1 } )

Sorts and the Positional Operator

When the find() method includes a sort(), the find() method applies the sort() to order the matching documents before it applies the positional $ projection operator.

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 $ projection operator.

Examples

Project Array Values

A collection students contains the following documents:

{ "_id" : 1, "semester" : 1, "grades" : [ 70, 87, 90 ] }
{ "_id" : 2, "semester" : 1, "grades" : [ 90, 88, 92 ] }
{ "_id" : 3, "semester" : 1, "grades" : [ 85, 100, 90 ] }
{ "_id" : 4, "semester" : 2, "grades" : [ 79, 85, 80 ] }
{ "_id" : 5, "semester" : 2, "grades" : [ 88, 88, 92 ] }
{ "_id" : 6, "semester" : 2, "grades" : [ 95, 90, 96 ] }

In the following query, the projection { "grades.$": 1 } returns only the first element greater than or equal to 85 for the grades field.

db.students.find( { semester: 1, grades: { $gte: 85 } },
                  { "grades.$": 1 } )

The operation returns the following documents:

{ "_id" : 1, "grades" : [ 87 ] }
{ "_id" : 2, "grades" : [ 90 ] }
{ "_id" : 3, "grades" : [ 85 ] }

Although the array field grades may contain multiple elements that are greater than or equal to 85, the $ projection operator returns only the first matching element from the array.

Project Array Documents

A students collection contains the following documents where the grades field is an array of documents; each document contain the three field names grade, mean, and std:

{ "_id" : 7, semester: 3, "grades" : [ { grade: 80, mean: 75, std: 8 },
                                       { grade: 85, mean: 90, std: 5 },
                                       { grade: 90, mean: 85, std: 3 } ] }

{ "_id" : 8, semester: 3, "grades" : [ { grade: 92, mean: 88, std: 8 },
                                       { grade: 78, mean: 90, std: 5 },
                                       { grade: 88, mean: 85, std: 3 } ] }

In the following query, the projection { "grades.$": 1 } returns only the first element with the mean greater than 70 for the grades field:

db.students.find(
   { "grades.mean": { $gt: 70 } },
   { "grades.$": 1 }
)

The operation returns the following documents:

{ "_id" : 7, "grades" : [  {  "grade" : 80,  "mean" : 75,  "std" : 8 } ] }
{ "_id" : 8, "grades" : [  {  "grade" : 92,  "mean" : 88,  "std" : 8 } ] }

Further Reading

$elemMatch (projection)