Working with two pipelines

Hi folks, I currently have two aggregations that I execute in my collections. I was wondering if it would be possible to turn them into a single one. Currently I execute each, and then on my app I merge the results.

There are two collections: Magazines and Pages, a Page has a “fk” to the Magazine _id.

The goal is to run a query that count how many pages per magazine have been reviewed (a boolean flag) but at the same time I need to return the magazine along with the very first page (cover).

So I first run the aggregation to get all magazines and its first page:

[{
 $match: {
  publication_id: 'egm'
 }
}, {
 $lookup: {
  from: 'Pages',
  localField: '_id',
  foreignField: 'magazine_id',
  as: 'pages'
 }
}, {
 $project: {
  issue: 1,
  page_count: 1,
  publication_id: 1,
  release_date: 1,
  language: 1,
  pages: {
   $filter: {
    input: '$pages',
    as: 'page',
    cond: {
     $eq: [
      '$$page.number',
      0
     ]
    }
   }
  }
 }
}]

Then I run the one to group the status of the reviewed pages:

[{
 $match: {
  publication_id: 'egm'
 }
}, {
 $group: {
  _id: {
   magazine_id: '$magazine_id',
   reviewed: '$reviewed'
  },
  count: {
   $count: {}
  },
  issue: {
   $first: '$issue_date'
  }
 }
}, {
 $group: {
  _id: '$_id.magazine_id',
  issue: {
   $first: '$issue'
  },
  status: {
   $push: {
    state: '$_id.reviewed',
    count: '$count'
   }
  }
 }
}, {
 $sort: {
  issue: 1
 }
}]

I then merge by the _id property on my code.

Can this be simplified by merging into a single pipeline or this is the way to do it?

Thank you

check this out: $facet (aggregation) — MongoDB Manual

it is basically multiple pipeline results assigned to new fields. you can then continue processing them down the main pipeline.

If I understand correctly what you mean by

you run one pipeline on the collection names Magazines and the other on the collection named Pages.

If it is the case then what you want is $unionWith rather than $facet.

1 Like