简体   繁体   中英

mongoose aggregate on a nested array

I have a schema that has a sub array and each of its elements reference another schema like so:

{
 _id: "5fed222d806311ec81d6df23"
 someOtherNestedDoc: {
    _id: "abc",
    someOtherField: 10
 },
 matches: [
   {
      _id: "5fed222d806311ec81d6daf3",
      user: "5fed222d806311ec81d6dcf3",
      probability: 10
   },
   {
      _id: "5fed222d806311ec81d6d1f3",
      user: "5fed222d806311ec81d62cf3",
      probability: 20
   },
 ]
}

I want to do a Mongoose aggregate, in which I lookup the user reference for every match, and only project 3 fields for it, 2 are already existing, the third one is the sum of an array of that schema, so that in the end, I have something like this:

{
 _id: "5fed222d806311ec81d6df23"
 someOtherNestedDoc: {
    _id: "abc",
    someOtherField: 10
 },
 matches: [
   {
      _id: "5fed222d806311ec81d6daf3",
      user: {
         firstName: "Max",
         lastName: "Mustermann",
         totalExpenses: 100
      },
      probability: 10
   },
   {
      _id: "5fed222d806311ec81d6d1f3",
      user: {
         firstName: "Herbert",
         lastName: "Mustermann",
         totalExpenses: 200
      },,
      probability: 20
   },
 ]
}

And the users would look like this:

{
  _id: "5fed222d806311ec81d6dcf3",
  firstName: "Max",
  lastName: "Mustermann",
  password: "test",
  expenses: [
    {
      _id: 1,
     price: 50
    },
    {
      _id: 2,
     price: 50
    },
   ]
}

{
  _id: "5fed222d806311ec81d62cf3",
  firstName: "Herbert",
  lastName: "Mustermann",
  password: "test2",
  expenses: [ 
    {
      _id: 3,
     price: 75
    },
    {
      _id: 4,
     price: 125
    },
   ]
}
  • $unwind deconstruct matches array
  • $lookup with user collection and pass user id in let,
    • $match userId condition
    • $project to show required fields, get sum of expenses.price
  • $unwind deconstruct user array
  • $group by _id and reconstruct matches array
db.col1.aggregate([
  { $unwind: "$matches" },
  {
    "$lookup": {
      "from": "user",
      let: { userId: "$matches.user" },
      pipeline: [
        { $match: { $expr: { $eq: ["$_id", "$$userId"] } } },
        {
          $project: {
            _id: 0,
            firstName: 1,
            lastName: 1,
            totalExpenses: { $sum: "$expenses.price" }
          }
        }
      ],
      "as": "matches.user"
    }
  },
  { $unwind: "$matches.user" },
  {
    $group: {
      _id: "$_id",
      matches: { $push: "$matches" }
    }
  }
])

Playground

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM