когда я создаю группу $, как я могу вернуть общую сумму собственности, присутствующей во всех объектах? - PullRequest
2 голосов
/ 05 августа 2020

У меня есть база данных со следующей структурой:

[
  {
    "provider": "provider 1",
    "debts": [
      {
        "debt": 500,
        "paid": true
      },
      {
        "debt": 900,
        "paid": false
      },
      {
        "debt": 600,
        "paid": false
      }
    ]
  },
  {
    "provider": "provider 2",
    "debts": [
      {
        "debt": 500,
        "paid": false
      }
    ]
  }
]

Я хочу, чтобы каждый объект сохранял в поле total сумму поля debt, содержащегося в массиве debts (debts.debt) ТОЛЬКО если свойство paid ложно. (в моем реальном коде он хорошо работает до этого момента).

db.collection.aggregate(
 [
  {
    $unwind: "$debts",
  },
      {
    $group: {
      _id: "$_id",

      total: {
        $sum: {
          $cond: [{ $eq: ["$debts.paid", false] }, "debts.debt", 0],
        },
      },
    },
  }
]

как я могу получить общую сумму свойства total, содержащегося во всех моих объектах, которые удовлетворяют вышеуказанному условию?

{
  "debts_providers": [
    {
      "_id": "5f29af0a17196c1624f7dd88",
      "total": 1500
    },
    {
      "_id": "5f29af0a17196c1624f7dd89",
      "total": 500
    }
  ],
  "sum_total_objects": 2000  /*900+600+500*/
}

Ответы [ 2 ]

1 голос
/ 05 августа 2020

Вы на правильном пути, просто нужно заменить root на debt_providers,

  • вы пропустили $ в первой группе $cond then часть, она должна быть $debts.debt
  • секунда $group, что требуется,
    • создать новое поле debt_providers и pu sh $$ROOT, потому что документы разворачиваются независимо, но нам нужно установить вместе в debt_providers
    • создать новое поле * от 1019 * до $sum все общее значение
db.collection.aggregate([
  {
    $unwind: "$debts"
  },
  {
    $group: {
      _id: "$_id",
      total: {
        $sum: {
          $cond: [
            { $eq: ["$debts.paid", false] }, 
            "$debts.debt", // corrected debts.debt to $debts.debt
            0
          ] 
        }
      }
    }
  },
  // added here
  {
    $group: {
      _id: null,
      debt_providers: { $push: "$$ROOT" },
      sum_total_objects: { $sum: "$total" }
    }
  }
])

Площадка: https://mongoplayground.net/p/esRanLrIB2o

1 голос
/ 05 августа 2020

Не нужно использовать $unwind - лучше обрабатывать массив с помощью $ reduce , чтобы суммировать только неоплаченные debts. Затем вам нужно $ группа , чтобы получить общее значение:

db.collection.aggregate([
    {
        $project: {
            _id: 1,
            total: {
                $reduce: {
                    input: "$debts",
                    initialValue: 0,
                    in: {
                        $add: [ "$$value", { $cond: [{ $eq: ["$$this.paid", false] }, "$$this.debt", 0] } ]
                    }
                }
            }
        }
    },
    {
        $group: {
            _id: null,
            debt_providers: { $push: "$$ROOT" },
            sum_total_objects: { $sum: "$total" }
        }
    }
])

Пн go Детская площадка

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