$ агрегация, $ сумма по двум коллекциям в MongoDB - PullRequest
1 голос
/ 20 февраля 2020

Привет, предположим, у меня есть эти две коллекции

sample1:

 {
    "_id" : {
            "date" : ISODate("2020-02-11T18:30:00Z"),
            "price" : 4,
            "offer" : 0,
            "itemCode" : "A001"
            "customerId" : ObjectId("5e43de778b57693cd46859eb"),
            "sellerId" : ObjectId("5e43e5cdc11f750864f46820"),
      },
    "charges" : 168
  }
  {
    "_id" : {
            "date" : ISODate("2020-02-11T18:30:00Z"),
            "coverPrice" :5.5 ,
            "offer" : 38,
            "itemCode" : "B001"
            "customerId" : ObjectId("5e43de778b57693cd46859eb"),
            "sellerId" : ObjectId("5e43e5cdc11f750864f46820"),
    },
    "charges" : 209.5
  }

ПРИМЕЧАНИЕ: sample1's _id не имеет ObjectId().

sample2:

        {
            "paymentReceivedOnDate" : ISODate("2020-02-12T18:30:00Z"),
             "customerId" : ObjectId("5e43de778b57693cd46859eb"),
            "sellerId" : ObjectId("5e43e5cdc11f750864f46820"),
            "amount" : 30,
         }
      {
            "paymentReceivedOnDate" : ISODate("2020-02-12T18:30:00Z"),
             "customerId" : ObjectId("5e43de778b57693cd46859eb"),
            "sellerId" : ObjectId("5e43e5cdc11f750864f46820"),
            "amount" : 160,
         }
     {
            "paymentReceivedOnDate" : ISODate("2020-02-11T18:30:00Z"),
             "customerId" : ObjectId("5e43de778b57693cd46859eb"),
            "sellerId" : ObjectId("5e43e5cdc11f750864f46820"),
            "amount" : 50,
        }

Мои постановки задачи:

1: Во-первых Мне нужно рассчитать итоговые расходы из образца 1 коллекции. против [date, customerId, sellerId]

2: Во-вторых, мне нужно рассчитать totalAmount из коллекции образца 2.

3: Чем я нужно вычислить непогашенный, т.е. [totalCharges - totalAmount].

4: и, наконец, самое главное, мне нужно сохранить прогнозируемый результат в новой коллекции. Предположим, «результат» со следующими полями - ['customerId', 'sellerId', 'date' , 'totalCharges', 'выдающийся' (то есть: [totalCharges - totalAmount]), 'totalAmount'.

1 Ответ

1 голос
/ 20 февраля 2020

Вы можете попробовать запрос ниже:

db.sample1.aggregate([
    /** groups data & sum up charges */
    { $group: { _id: { date: '$_id.date', customerId: '$_id.customerId', sellerId: '$_id.sellerId' }, totalCharges: { $sum: '$charges' } } },
    /** finds matching docs from sample2 */
    {
        $lookup:
        {
            from: "sample2",
            let: { customerId: '$_id.customerId', sellerId: '$_id.sellerId' },
            pipeline: [
                {
                    $match:
                    {
                        $expr:
                        {
                            $and:
                                [
                                    { $eq: ["$customerId", "$$customerId"] },
                                    { $eq: ["$sellerId", "$$sellerId"] }
                                ]
                        }
                    }
                },
                { $project: { amount: 1, _id: 0 } }
            ],
            as: "TotalAmount" // TotalAmount is an array of objects, each object will have just amount field in it.
        }
    },
    /** retains only needed fields  */
    {
        $project: {
            totalCharges: 1, outstanding: {
                $subtract: ['$totalCharges', {
                    $reduce: {
                        input: '$TotalAmount',
                        initialValue: 0,
                        in: { $add: ["$$value", "$$this.amount"] }
                    }
                }]
            }, TotalAmount: {
                $reduce: {
                    input: '$TotalAmount',
                    initialValue: 0,
                    in: { $add: ["$$value", "$$this.amount"] }
                }
            }
        }
    }
])

Тест: MongoDB-Playground

Ссылка: конвейер агрегации

Примечание: В конце агрегации вы можете иметь либо $ merge , либо $ out stage чтобы записать результаты агрегации в новую коллекцию, если ваш MongoDB v> = 4.2, а затем предпочитает $merge, потому что он объединит поля с существующими документами / добавит новые документы в существующую коллекцию или если коллекция с указанным именем не найдена, он создаст новый collection, но где $out полностью заменит существующую коллекцию, если предоставленное имя коллекции уже существует, или создаст новую коллекцию с предоставленным именем.

...