Как сгруппировать данные по периоду времени?

У меня есть данные о счетах-фактурах, и я хочу сгруппировать их по стене периода времени. например 0-10 и 11-20:

Мне нужно решить их с помощью $aggregate в mongoDB.

{
    '_id': '1',
    'value': 10,
    'due_date': '20221001'
},
{
    '_id': '2',
    'value': 10,
    'due_date': '20221012'
},
{
    '_id': '2',
    'value': 10,
    'due_date': '20221030'
},

Мне нужно сгруппировать по периодам 0-10 дней, 11-20 дней и суммировать значения: для приведенного выше примера результат будет таким:

[{
    "_id": '0-10 days',
    "total": 10,
},
{
    "_id": '11-20 days',
    "total": 10,
},
{
    "_id": '>20 days',
    "total": 10,
}]

Я пытаюсь с:

['$facet' => [
  ['due_date_one' => [
      ['$match' => [
         'due_date' => [
           '$gt'    => new UTCDateTime((new Carbon())-> subDays(100) -> getTimestamp()),
            '$lte'  => date('Y-m-d', strtotime('now'))
         ]
         ]
     ]],
]]

Отсчитывается с сегодняшнего дня

Marlon code 11.11.2022 07:52

Покажите нам, что вы уже пробовали?

Sachin Bahukhandi 11.11.2022 08:36

«Мне нужно решить их с помощью $aggregate в mongoDB». - тогда почему этот вопрос помечен как PHP или Laravel?

Nico Haase 11.11.2022 09:22

Потому что я использую mongoDB в php laravel

Marlon code 11.11.2022 09:33

Я считаю, что ответил на ваш вопрос, можете ли вы проверить, проголосовать и принять / прокомментировать, пожалуйста.

dangarfield 11.11.2022 12:18
Шлюз в PHP
Шлюз в PHP
API-шлюз (AG) - это сервер, который действует как единая точка входа для набора микросервисов.
Socialite Login With Google Account In Laravel 9
Socialite Login With Google Account In Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com.
Обновление драйверов Microsoft ODBC (с 17 до 18) для PHP
Обновление драйверов Microsoft ODBC (с 17 до 18) для PHP
Все знают, что PHP v7.4 потерял поддержку, и наши недавние старые приложения должны обновиться до PHP v8.x. ...
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как создать PHP Image с нуля
Как создать PHP Image с нуля
Сегодня мы создадим PHP Image from Scratch для того, чтобы легко развернуть базовые PHP-приложения. Пожалуйста, имейте в виду, что это разработка для...
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
0
5
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать $bucket или добавить несколько этапов $addFields и $group:

Пример игровой площадки монго - https://mongoplayground.net/p/B0zl_GGH4sG

Примеры документов:

[
  {
    "_id": "1a",
    "value": 10,
    "due_date": "20221001"
  },
  {
    "_id": "1b",
    "value": 5,
    "due_date": "20221102"
  },
  {
    "_id": "1c",
    "value": 7,
    "due_date": "20221102"
  },
  {
    "_id": "2a",
    "value": 10,
    "due_date": "20221012"
  },
  {
    "_id": "2b",
    "value": 7,
    "due_date": "20221113"
  },
  {
    "_id": "2c",
    "value": 8,
    "due_date": "20221113"
  },
  {
    "_id": "3a",
    "value": 10,
    "due_date": "20221030"
  },
  {
    "_id": "3b",
    "value": 9,
    "due_date": "20221131"
  },
  {
    "_id": "3c",
    "value": 11,
    "due_date": "20221131"
  }
]

Совокупный запрос:

db.collection.aggregate([
  {
    $addFields: {
      day: {
        $toInt: { $substr: [ "$due_date", 6, 2 ] }
      }
    }
  },
  {
    $addFields: {
      bucketDate: {
        $switch: {
          branches: [
            { case: { $gt: [ "$day", 20 ] }, then: ">20 days" },
            { case: { $gt: [ "$day", 10 ] }, then: "11-20 days" }
          ],
          "default": "0-10 days"
        }
      }
    }
  },
  {
    $addFields: {
      bucketDateWithMonth: {
        $concat: [
          { $substr: [ "$due_date", 0, 6 ] },
          " ",
          "$bucketDate"
        ]
      }
    }
  },
  {
    $group: {
      //_id: "$bucketDate", //No grouped month
      _id: "$bucketDateWithMonth", //With grouped month
      count: { $sum: 1 },
      value: { $sum: "$value" }
    }
  }
])

Вывод: (сгруппированный месяц)

[
  {
    "_id": "202210 0-10 days",
    "count": 1,
    "value": 10
  },
  {
    "_id": "202211 0-10 days",
    "count": 2,
    "value": 12
  },
  {
    "_id": "202210 11-20 days",
    "count": 1,
    "value": 10
  },
  {
    "_id": "202211 11-20 days",
    "count": 2,
    "value": 15
  },
  {
    "_id": "202210 \u003e20 days",
    "count": 1,
    "value": 10
  },
  {
    "_id": "202211 \u003e20 days",
    "count": 2,
    "value": 20
  }
]

Вывод: (нет сгруппированного месяца)

[
  {
    "_id": "\u003e20 days",
    "count": 3,
    "value": 30
  },
  {
    "_id": "0-10 days",
    "count": 3,
    "value": 22
  },
  {
    "_id": "11-20 days",
    "count": 3,
    "value": 25
  }
]

Другие вопросы по теме