Working with Projection
1. Including Fields
| Form | Effect |
{name: 1, email: 1} | Include + _id by default |
{name: 1, _id: 0} | Exclude _id explicitly |
| Rule | Cannot mix include/exclude (except _id) |
2. Excluding Fields
| Form | Effect |
{password: 0} | Exclude; everything else included |
{password: 0, "internal.secret": 0} | Nested exclusion |
3. Projecting Array Elements
| Operator | Effect |
$slice: n | First n (or last if negative) |
$slice: [skip, limit] | Window |
$elemMatch | First element matching condition |
$ | First element matching query filter |
db.posts.find({}, { comments: { $slice: -3 } }); // last 3 comments
4. Using $elemMatch in Projection
| Aspect | Detail |
| Returns | First array element matching condition |
| Differs from $ | Condition specified in projection (not query) |
db.classes.find({}, { students: { $elemMatch: { grade: { $gte: 90 } } } });
5. Projecting Positional Elements ($)
| Aspect | Detail |
| Syntax | { "items.$": 1 } |
| Returns | Only the first matching element from query filter |
| Limitation | Only one positional projection per query |
6. Excluding _id Field
| Form | Effect |
{_id: 0, name: 1} | Only valid mix of include/exclude |
| Use case | Cleaner export, joining external systems |
7. Using $meta for Text Search Scores
| Field | Returns |
{$meta: "textScore"} | Relevance score (requires $text query) |
{$meta: "indexKey"} | Index key used (debugging) |
{$meta: "searchScore"} | Atlas Search score |
{$meta: "searchHighlights"} | Atlas Search highlights |
8. Projecting Nested Fields
| Form | Effect |
{"profile.city": 1} | Dot notation include |
{profile: {city: 1}} | Nested object form |
| Aggregation | Use $project with expressions for renaming |
9. Understanding Projection Limitations
| Limitation | Detail |
| No mix include/exclude | Except _id |
| One $ per query | Multiple positional updates need filtered ($[id]) |
| Field renaming | Not in find(); use aggregation $project |
| Computed fields | Aggregation only (find supports limited 4.4+ expressions) |
| Benefit | How |
| Network bytes ↓ | Exclude large fields (images, blobs) |
| Covered query | All projected fields in index → no doc fetch |
| CPU ↓ | Less BSON serialization |
| Memory ↓ | Smaller client-side objects |
Note: A covered query requires projection that includes ONLY indexed fields and excludes _id (unless _id is part of the index).