发布于 2015-09-14 15:05:44 | 147 次阅读 | 评论: 0 | 来源: 网络整理
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 } )
Example
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.
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.
Example
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. The query also includes a sort() to order by ascending grades.grade field:
db.students.find( { "grades.mean": { $gt: 70 } },
{ "grades.$": 1 }
).sort( { "grades.grade": 1 } )
The find() method sorts the matching documents before it applies the $ projection operator on the grades array. Thus, the results with the projected array elements do not reflect the ascending grades.grade sort order:
{ "_id" : 8, "grades" : [ { "grade" : 92, "mean" : 88, "std" : 8 } ] }
{ "_id" : 7, "grades" : [ { "grade" : 80, "mean" : 75, "std" : 8 } ] }
注解
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 (query) operator, e.g.:
db.students.find( { grades: { $elemMatch: {
mean: { $gt: 70 },
grade: { $gt:90 }
} } },
{ "grades.$": 1 } )
也可以参考