querydrill

Learn ›Aggregation ›The aggregation pipeline

$project and computed fields

$multiply$project

$project decides what a document looks like coming out of a stage. It does the job of a projection in find(), and then keeps going - it can rename fields and compute entirely new ones.

Suppose your document is:

{
  _id: 1,
  userId: 101,
  status: "completed",
  createdAt: "...",
  internalNotes: "...",
  items: [...]
}

You only want:

userId
status
{
  $project: {
    userId: 1,
    status: 1
  }
}

Result:

{
  _id: 1,
  userId: 101,
  status: "completed"
}

Like normal projection, _id is included unless excluded.

{
  $project: {
    _id: 0,
    userId: 1,
    status: 1
  }
}

$project Can Also Create Fields

This is where aggregation starts becoming interesting.

Suppose:

{
  product: "Laptop",
  price: 1000,
  quantity: 2
}

You can calculate:

{
  $project: {
    product: 1,

    total: {
      $multiply: [
        "$price",
        "$quantity"
      ]
    }
  }
}

Result:

{
  product: "Laptop",
  total: 2000
}

Notice:

"$price"

The $ means:

Take the value from this document’s price field.

Compare:

price

Literal/string conceptually.

vs:

"$price"

Field reference.

This is one of the most important syntax rules in aggregation.

Try it

db.orders.aggregate([
  {
    $project: {
      _id: 0,
      userId: 1,
      status: 1
    }
  },
  { $limit: 5 }
])

Everything not named is gone. Drop the _id: 0 line and it comes back.

Practise this

1 exercise