querydrill

Learn ›Advanced aggregation ›Joining collections with $lookup

$lookup, and why it returns an array

MongoDB can join, and $lookup is how. The detail that trips everyone on their first attempt: the joined result is always an array, even when exactly one document matched.

Suppose we have:

orders

{
  _id: 1,
  userId: 101,
  amount: 1000
}

users

{
  _id: 101,
  name: "Denish",
  email: "denish@example.com"
}

We want:

{
  orderId: 1,
  amount: 1000,
  user: {
    name: "Denish"
  }
}

Basic $lookup

db.orders.aggregate([
  {
    $lookup: {
      from: "users",
      localField: "userId",
      foreignField: "_id",
      as: "user"
    }
  }
])

Think:

orders.userId
       ↓
matches
       ↓
users._id

Result:

{
  _id: 1,
  userId: 101,
  amount: 1000,

  user: [
    {
      _id: 101,
      name: "Denish",
      email: "denish@example.com"
    }
  ]
}

⚠️ Important: $lookup Returns an Array

Even if there is only one matching user:

user: [
  {
    name: "Denish"
  }
]

That surprises people.

If you know there is one user, you usually want:

user[0]

There are multiple ways to handle this.

Practise this

1 exercise