Home > Back-end >  MongoDB - How to combine findOne (in array) with aggregate
MongoDB - How to combine findOne (in array) with aggregate

Time:10-04

I currently have a Mongo query that looks like this:

const user = await User.findOne({ userId }).lean() || []

const contributions = await Launch.aggregate([
  { $sort: { addedAt: -1 } },
  { $limit: 10 },
  {
    $match: {
      _id: { $in: user.contributions }
    }
  },
  {
    $addFields: {
      activity: 'contribution',
      launchName: '$name',
      launchId: '$_id',
      date: '$addedAt',
      content: '$description'
    }
  }
])

But instead of having two different Mongo queries (findOne and aggregate), how can I combine them into one query?

I tried this but it just errors out immediately in the lookup part:

const contributions = await Launch.aggregate([
  { $sort: { addedAt: -1 } },
  { $limit: 10 },
  {
    $lookup: {
      from: 'user',
      let: { id: $user.contributions },
      pipeline: [
        { $match: { $expr: { $in: [$_id, $$user.contributions] } } }
      ],
      localField: '_id',
      foreignField: 'userId',
      as: 'user'
    }
  },
  {
    $addFields: {
      activity: 'contribution',
      launchName: '$name',
      launchId: '$_id',
      date: '$addedAt',
      content: '$description'
    }
  }
])

I've never used the pipeline option so a little confused onn how to fix this problem?

CodePudding user response:

  1. Enclose these $user.contributions, $_id with quotes in order to make the query valid.

  2. Since you declare the id variable with the value of user.contributions. You should use the variable with $$id instead of $$user.contributions.

  3. I don't think the localField and foreignField are needed as you are mapping/joining with pipeline.

Your aggregation query should be looked as below:

const contributions = await Launch.aggregate([
  { $sort: { addedAt: -1 } },
  { $limit: 10 },
  {
    $lookup: {
      from: 'user',
      let: { id: "$user.contributions" },
      pipeline: [
        { $match: { $expr: { $in: ["$_id", "$$id"] } } }
      ],
      as: 'user'
    }
  },
  {
    $addFields: {
      activity: 'contribution',
      launchName: '$name',
      launchId: '$_id',
      date: '$addedAt',
      content: '$description'
    }
  }
])
  • Related