$ unwind, $ манипулирование агрегацией в mongodb nodejs - PullRequest
1 голос
/ 25 февраля 2020

, пожалуйста, проверьте этот запрос

   db.billsummaryofthedays.aggregate([
    {
        '$match': {
            'userId': ObjectId('5e43de778b57693cd46859eb'),
            'adminId': ObjectId('5e43e5cdc11f750864f46820'),
            'date': ISODate("2020-02-11T16:30:00Z"),
        }
    },
         {
           $lookup:
           {
               from: "paymentreceivables",
               let: { userId: '$userId', adminId: '$adminId' },
               pipeline: [
                   {
                       $match:
                       {
                        paymentReceivedOnDate:ISODate("2020-02-11T16:30:00Z"),
                           $expr:
                           {
                               $and:
                                   [
                                       { $eq: ["$userId", "$$userId"] },
                                       { $eq: ["$adminId", "$$adminId"] }
                                   ]
                           }
                       }
                   },
                   { $project: { amount: 1, _id: 0 } }
               ],
               as: "totalPayment"         
           }
       }, {'$unwind':'$totalPayment'},
       {   $group:
        { _id:
           { date: '$date',
           userId: '$userId',
            adminId: '$adminId' },
          totalBill:
             {
                  $sum: '$billOfTheDay'    
           },
             totalPayment:
             {
                  $sum: '$totalPayment.amount'
           }
       }
   },
       }
   }])

это результат, который я получаю в оболочке

   {
    "_id" : {
            "date" : ISODate("2020-02-11T18:30:00Z"),
            "userId" : ObjectId("5e43de778b57693cd46859eb"),
            "adminId" : ObjectId("5e43e5cdc11f750864f46820")
    },
    "totalBill" : 1595.6799999999998,
    "totalPayments" : 100
   }

теперь это не то, что я ожидал, я предположим, что из-за {'$unwind':'$totalPayment'} он извлекает все значения из массива и из-за чего каждый документ подсчитывается 2 раза. Когда я удаляю {'$unwind':'$totalPayment'}, тогда totalBill сумма оказывается правильной, но totalPayment равен 0. Я пробовал несколько других способов, но не смог достичь желаемого результата. Ниже приведены мои коллекции:

    // collection:billsummaryofthedays//
      {
        "_id" : ObjectId("5e54f784f4032c1694535c0e"),
        "userId" : ObjectId("5e43de778b57693cd46859eb"),
        "adminId" : ObjectId("5e43e5cdc11f750864f46820"),
        "date" : ISODate("2020-02-11T16:30:00Z"),
        "UID":"acex01"
        "billOfTheDay" : 468,
     }
     {
        "_id" : ObjectId("5e54f784f4032c1694535c0f"),
         "UID":"bdex02"
        "userId" : ObjectId("5e43de778b57693cd46859eb"),
        "adminId" : ObjectId("5e43e5cdc11f750864f46820"),
        "date" : ISODate("2020-02-11T16:30:00Z"),
         "billOfTheDay" : 329.84,
       }
    // collection:paymentreceivables//
     {
        "_id" : ObjectId("5e43e73169fe1e3fc07eb7c5"),
        "paymentReceivedOnDate" : ISODate("2020-02-11T16:30:00Z"),
        "adminId" : ObjectId("5e43e5cdc11f750864f46820"),
        "userId" : ObjectId("5e43de778b57693cd46859eb"),
        "amount" : 20,
       }
      {
        "_id" : ObjectId("5e43e73b69fe1e3fc07eb7c6"),
        "paymentReceivedOnDate" : ISODate("2020-02-11T16:30:00Z"),
        "adminId" : ObjectId("5e43e5cdc11f750864f46820"),
        "userId" : ObjectId("5e43de778b57693cd46859eb"),
        "amount" : 30,
       }

желаемый результат должен быть totalBill:797.83, т. Е. [468 + 329,84,] и totalPayment:50, т. Е. [30 + 20,] , но я получаю вдвое больший ожидаемый результат, и даже если я могу вычислить один из значение правильно другой результат 0. Как решить эту проблему?

1 Ответ

2 голосов
/ 25 февраля 2020

Поскольку у вас есть несколько документов с одинаковыми данными в коллекции billsummaryofthedays , вы можете сначала сгруппировать, а затем выполнить $lookup - таким образом, JOIN между двумя коллекциями будет 1 - против - много вместо много - против - много как написано в данный момент, так что вы можете попробовать запрос ниже для желаемого увеличения производительности и производительности:

db.billsummaryofthedays.aggregate([
  {
    "$match": {
      "userId": ObjectId("5e43de778b57693cd46859eb"),
      "adminId": ObjectId("5e43e5cdc11f750864f46820"),
      "date": ISODate("2020-02-11T16:30:00Z"),

    }
  },
  {
    $group: {
      _id: {
        date: "$date",
        userId: "$userId",
        adminId: "$adminId"
      },
      totalBill: {
        $sum: "$billOfTheDay"
      }
    }
  },
  {
    $lookup: {
      from: "paymentreceivables",
      let: {
        userId: "$_id.userId",
        adminId: "$_id.adminId"
      },
      pipeline: [
        {
          $match: {
            paymentReceivedOnDate: ISODate("2020-02-11T16:30:00Z"),
            $expr: {
              $and: [
                {
                  $eq: [
                    "$userId",
                    "$$userId"
                  ]
                },
                {
                  $eq: [
                    "$adminId",
                    "$$adminId"
                  ]
                }
              ]
            }
          }
        },
        {
          $project: {
            amount: 1,
            _id: 0
          }
        }
      ],
      as: "totalPayment"
    }
  },
  {
    $addFields: {
      totalPayment: {
        $reduce: {
          input: "$totalPayment",
          initialValue: 0,
          in: {
            $add: [
              "$$value",
              "$$this.amount"
            ]
          }
        }
      }
    }
  }
])

Тест: MongoDB-Playground

...