querydrill

Learn ›Aggregation ›The aggregation pipeline

$sort, $limit, $skip — order matters

$limit$match$skip$sort

These behave like their find() counterparts, with one difference that matters far more in a pipeline: they are stages, so their position changes the result. $limit before $sort is a different query from $sort before $limit.

{
  $sort: {
    createdAt: -1
  }
}

Multiple fields:

{
  $sort: {
    userId: 1,
    createdAt: -1
  }
}

$limit and $skip

{
  $limit: 10
}
{
  $skip: 20
}

Example:

db.orders.aggregate([
  {
    $match: {
      status: "completed"
    }
  },
  {
    $sort: {
      createdAt: -1
    }
  },
  {
    $skip: 20
  },
  {
    $limit: 10
  }
])

⚠️ Order Matters

This:

$sort
↓
$limit

means:

Find the top 10 after sorting.

But:

$limit
↓
$sort

means:

Take the first 10 arbitrary/current-order documents, then sort only those 10.

Aggregation is a pipeline.

Every stage receives the output of the previous stage.

This sounds obvious, but it is one of the biggest sources of mistakes.