Skip to content
Monghoul

Join two collections with $lookup

Build a $lookup stage in the visual builder, and use the autocomplete that keeps working on the joined fields afterwards.

Checked against v1.11.0 Updated
The aggregation builder on a $lookup stage, with the Lookup Helper form filled in: from customers, localField customerId, foreignField _id, as customer
Aggregation builder · The $lookup helper names the four fields, and syncs with the code

$lookup is the stage people write wrong most often, mostly because nothing tells you whether the field names are right until the pipeline returns an empty array.

Use the form helper

  1. Open a query tab on the collection you are joining from.
  2. Switch the editor to Builder.
  3. Add a $lookup stage. The form asks for the foreign collection, the local field, the foreign field, and the output name.
  4. Preview the stage. Automatic refresh is off by default, so ask for the preview, or turn auto-refresh on and it will re-run after a pause in typing. Each stage previews its own output, so you see the joined array appear rather than finding out at the end. A preview carries a 20-document safety limit unless you turn it off.

If the joined array is empty, the local and foreign fields do not match in type. An ObjectId in one collection and its string form in the other is the usual cause, and it looks identical in a tree view. Switch that field to JSON view to see which one is {"$oid": ...}.

The part that pays off afterwards

Once the $lookup is in the pipeline, autocomplete knows about the fields it produced. Type the output name and a dot, and you get the foreign collection’s schema, nested paths included.

That keeps working through the stages that reshape documents: $project, $group, $count, $facet, $bucket and $unset. A field an earlier stage created is still offered eight stages later, which is the thing this editor does that a plain shell does not. Where a stage’s output cannot be derived, a computed $replaceRoot for example, the whole document is kept instead.

Switch back to code whenever you like

Visual and code modes round-trip a pipeline the builder can read, so you can start in the form and finish by typing.

Two limits are worth knowing. A pipeline the builder cannot fully read is reduced to the part it understood, and that reduction is written back on your first edit, so surrounding statements, comments, a trailing .explain() and a second options argument do not survive the trip. And undo covers structural edits only: adding, moving, duplicating, enabling and clearing a stage, up to 50 entries. Typing inside a stage body is not undoable from the pipeline history.

Watch the plan

A $lookup without an index on the foreign field is a collection scan per input document. Run the pipeline, open Explain, and check. Reading an explain plan covers what to look for.

Next