1

I'm here to ask you about one problem that has kept me struggling in several projects and I don't know which is the best way to do it.

The problem is:

I am querying a MongoDB collection, called Likes, that has this schema:

  user: { type: Schema.Types.ObjectId, ref: 'User', required: true, index: true },
  product: { type: Schema.Types.ObjectId, ref: 'Product', index: true },
  list: { type: Schema.Types.ObjectId, ref: 'List', index: true },
  deleted: { type: Boolean, default: false }

I want to get all the items that belong to a certain user, not deleted yet, and paginated. And in the same query, I want to populate certain fields of that documents, so I do:

Like.find({ user: req.params.user_id, deleted: false })
  .skip((page - 1) * limit)
  .limit(limit)
  .populate([
    { path: 'product'},
    {
      path: 'list',
      match: { deleted: false },
      populate: [
        { path: 'items.product' },
        { path: 'users.user' }
      ]
    }
  ])

It works as expected. But the thing is, as we are matching non deleted lists in the populate functions, there are some documents with list property set to null.

We want to return always as much documents as we can up to limit without any null list, but we can't filter them out. Because if the query returns 24 items, and we filter out 2 of them, there will be a gap between the number of returned results and the limit.

Which is the best way to do it? I tried with aggregates also, but it gets messy because of the many things that we need to populate.

jesusbotella
  • 626
  • 4
  • 8
  • If you need to actually filter the "parent" data returned, modern MongoDB releases actually support "joins" on the server via `$lookup`, which allows filtering of the content "before" you actually return the results from the server. Whilst a little more terse in syntax, this somewhat makes `.populate()` redundant. Especially when considering an approach like I added to [Querying after populate in Mongoose](https://stackoverflow.com/a/44688386/2313887). Where the given code there will only return parents where a child was matched. – Neil Lunn Jun 24 '17 at 03:39
  • Note that the function [implemented as a static in that post](https://stackoverflow.com/a/44688386/2313887), need only be defined once and can be re-used. – Neil Lunn Jun 24 '17 at 03:41

0 Answers0