Агрегировать, группировать, вычислять и проецировать данные в MongoDB - PullRequest
0 голосов
/ 02 августа 2020
{ _id : 5f206f44e51c8026b2222f74 , order : 1 , type : purchased , amount : 1000 }
{ _id : 5f207065e51c8026b2222f75 , order : 1 , type : processed , productType : good , amount : 700 }
{ _id : 5f20716fe51c8026b2222f77 , order : 1 , type : processed , productType : small , amount : 100 }
{ _id : 5f2071b5e51c8026b2222f78 , order : 1 , type : processed , productType : shrinked , amount : 100 }
{ _id : 5f2073a5abd40426b2650033 , order : 1 , type : processed , productType : waste , amount : 100 }
{ _id : 5f207220e51c8026b2222f79 , order : 1 , type : shipped , amount : 500 }

Business logi c: Товар (в заказе) приобретен, обработан (получено несколько "productType") и отправлен.

Ожидается: Группа по заказу, типу, типу продукта, сумме и вычислить остаток.

Ожидаемый результат:

{
    order: 1,
    purchased: 1000,
    processed: 1000,
    productTypes: {
        good: 700,
        small: 100,
        shrinked: 100,
        waste: 100
    },
    shipped: 500,
    productBalance: 500
}

Пока мне удалось сгруппировать элементы по заказам и типам:

Запрос:

{
    $group: {
          _id: {
                    "order": "$order",
                    "type": "$type"
                },
          logs: { $push: "$$ROOT" },
          totalAmount: { $sum: "$amount" }
    }
}

{
    $group: {
          _id: "$_id.order",
          types: {
              $push: { 
                type: "$_id.type", 
                totalAmount: "$totalAmount", 
                logs: "$logs"
              } 
          }
    }
}

Запрос изображения (Компас)

Результат:

{
    order: 1,
    types: [
        { 
            type: "purchased",
            totalAmount: 1000,
            logs: [ ... ]
        },
        { 
            type: "processed",
            totalAmount: 1000,
            logs: [ 
                {
                    type:"processed"
                    productType:"small"
                    amount:100
                },
             ... ]
        },
    ]
}

1 Ответ

0 голосов
/ 02 августа 2020
[{$group: {
  _id: {
    order: '$order',
    type: '$type'
  },
 logs:{
   $push:{
     productType:{$ifNull:["$productType","removeElement"]},
     amount:{
       $sum:"$amount"
     }
   }
 },
 total:{
   $sum:"$amount"
 }
}}, {$project: {
  order:"$_id.order",
  type:"$_id.type",
  total:1,
  productType:{
    "$arrayToObject": {
      "$map": {
        "input": "$logs",
        "in": {
          "k": "$$this.productType",
          "v": "$$this.amount"
        }
      }
    }
  }
}}, {$project: {
  "productType.removeElement":0
}}, {$group: {
  _id: "$order",
  typeAmount: {
    $push: {
      type:"$type",
      amount:"$total"
    }
  },
  productType:{
    $push:"$productType"
  }
}}, {$project: {
  order:"$_id",
  typeAmount:{
    "$arrayToObject": {
      "$map": {
        "input": "$typeAmount",
        "in": {
          "k": "$$this.type",
          "v": "$$this.amount"
        }
      }
    }

    },
  productType:{
    $filter:{
      input:"$productType",
      cond:{
        $ne:["$$this",{}]
      }
    }
  },
  _id:0
}}, {$replaceRoot: {
  newRoot: {
    "$mergeObjects": ["$typeAmount","$$ROOT"]
  }

    }}, {$project: {
  typeAmount:0

  }}]

Рабочий Пн go площадка . Вопрос не в том, как рассчитать productBalance. Надеюсь, проблем не будет. productType - это массив, если он может иметь только один объект, вы можете использовать $arrayElemAt или просто $unwind("$productType"), чтобы сделать его объектом

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...