kibe
kibe

Reputation: 181

How to use findOne and aggregate at the same time in MongoDB?

Say I have a list of users. A user has

username,
email,
password,
sketches

sketches is another collection, and a sketch has

title
author

If I want to fetch a user with his/her sketches, I have to use aggregate to find all sketches that have author as his/her username.

This is working great:

const data = await userModel
  .aggregate([
    { $match: { username } },
    { $lookup: { from: 'sketches', localField: 'username', foreignField: 'author', as: 'sketches' } },
    { $limit: 1 }
   ]).toArray()

The issue is that some users don't have sketches; when a user has no sketches, the aggregate does not return anything else about the user, so username, email, and password becomes undefined.

Is there any way I can make aggregate sort of optional? Like find the user and then try to see if they have any sketches.

Thanks!

Upvotes: 0

Views: 345

Answers (1)

D. SM
D. SM

Reputation: 14520

$lookup performs an outer join, it does not drop fields of the base document when there are no documents to join.

MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.insert({a:1})
WriteResult({ "nInserted" : 1 })
MongoDB Enterprise ruby-driver-rs:PRIMARY> db.foo.aggregate([{$lookup:{from:'bogus',localField:'x',foreignField:'y',as:'z'}}])
{ "_id" : ObjectId("5f2c5fbd0b0bc72d0ed504d3"), "a" : 1, "z" : [ ] }

See also If Mongo $lookup is a left outer join, then how come it excludes non-matching documents?

Upvotes: 1

Related Questions