[ EXECUTIVE TEARDOWN // TL;DR ]

Put $match first and on indexed fields — every document eliminated early is one the rest of the pipeline never touches.

$lookup is a join: run it late (after match/limit) and index the foreign field, or it degrades to repeated scans.

Profile with explain('executionStats') and reorder by the real numbers, not intuition.

Design pipelines bottom-up: find the smallest set, then ensure every stage operates only on it.