The second argument to find() says which fields come back. 1 includes, 0 excludes, and the two cannot be mixed — the server answers Location31254: Cannot do exclusion on field year in inclusion projection. The exception is _id, included by default and switchable off alongside inclusions. A dotted path keeps the surrounding structure, so 'author.name' returns an author subdocument holding only name.
Three operators shape arrays here: $slice takes the first n elements (the last n if negative, or [skip, limit]), $elemMatch returns the first element matching a condition, and the positional $ the first element the filter matched. find() also accepts aggregation expressions, so a computed field needs no pipeline.
db.books.find({ _id: 3 }, { title: 1, 'author.name': 1 })
db.books.find({ _id: 3 }, { editions: 0, ratings: 0, tags: 0, author: 0 })
db.books.find({ _id: 1 }, { title: 1, _id: 0, ratings: { $slice: -1 } })
db.books.find({ _id: 1 }, { _id: 0, title: 1, reviews: { $size: '$ratings' },
cheap: { $lt: ['$price', 13] } })[ { _id: 3, title: 'The Hobbit', author: { name: 'J. R. R. Tolkien' } } ]
[ { _id: 3, title: 'The Hobbit', year: 1937, price: 14, stock: 12 } ]
[ { title: 'Dune', ratings: [ 3 ] } ]
[ { title: 'Dune', reviews: 4, cheap: true } ]Less data over the wire is the obvious win; the bigger one is that a query whose filter and projection are both covered by an index never touches the documents at all (Covered Queries). A computed projection is an aggregation expression evaluated per document, so reviews and cheap count as inclusions, barred from mixing with 0 exclusions.