Фильтр Транзакции, происходящие в набор дат - PullRequest
1 голос
/ 11 марта 2020

У меня есть запрос, который я использую для суммирования транзакций, приходящихся на даты. Теперь я sh буду использовать $ match для фильтрации транзакций, приходящихся на набор дат.

В столбце дат поднял_дата, это отметка времени, поэтому сначала я использую $toDate, чтобы преобразовать его в дату и отформатировать в строку даты.

Мой рабочий агрегатный запрос для вычисления итоговых сумм по датам выглядит примерно так -

db.transactions.aggregate([{
    "$group": {
        "_id": {
            "$dateToString": {
                format: "%Y-%m-%d",
                date: {
                    "$toDate": "$raised_date"
                }
            }
        },
        amount_total: {
            $sum: "$amount"
        }
    }
}])

Он дает мне данные:

{ "_id" : "2019-05-13", "amount_total" : 2000 }
{ "_id" : "2019-05-28", "amount_total" : 78 }
{ "_id" : "2019-09-19", "amount_total" : 3000 }
{ "_id" : "2019-01-05", "amount_total" : 9034 }
{ "_id" : "2019-04-15", "amount_total" : 2600 }
{ "_id" : "2019-11-14", "amount_total" : 2870 }
{ "_id" : "2019-09-16", "amount_total" : 1500 }
{ "_id" : "2019-09-18", "amount_total" : 7200 }
{ "_id" : "2019-04-11", "amount_total" : 106034 }
{ "_id" : "2019-03-13", "amount_total" : 2000 }
{ "_id" : "2019-04-30", "amount_total" : 2302 }
{ "_id" : "2019-01-08", "amount_total" : 4665 }
{ "_id" : "2019-05-03", "amount_total" : 83 }
{ "_id" : "2019-08-03", "amount_total" : 2500 }
{ "_id" : "2019-03-04", "amount_total" : 350930 }
{ "_id" : "2019-12-10", "amount_total" : 1819 }
{ "_id" : "2019-03-12", "amount_total" : 15002 }
{ "_id" : "2019-05-08", "amount_total" : 78 }
{ "_id" : "2019-12-12", "amount_total" : 2370 }

Тогда я Я могу фильтровать эти транзакции на основе таких дат, как эта

db.transactions.aggregate([{
    "$group": {
        "_id": {
            "$dateToString": {
                format: "%Y-%m-%d",
                date: {
                    "$toDate": "$raised_date"
                }
            }
        },
        amount_total: {
            $sum: "$amount"
        }
    }
},
{
    $match: {
        _id: {
            $in: ["2019-05-13"]
        }
    }
}])

Что дает мне данные:

{ "_id" : "2019-05-13", "amount_total" : 2000 }

Я считаю, что лучше фильтровать данные перед агрегациями, в огромных таблицах, поэтому я sh хочу добавить запрос $ match в начале.

Теперь я пытаюсь изменить его, чтобы отфильтровать данные на основе набора дат, используя запрос на совпадение. Как отфильтровать записи, когда мне нужно изменить значения в столбцах и проверить, есть ли они в списке дат.

db.transactions.aggregate([{
    "$match": {
        {
              "$dateToString": {
              format: "%Y-%m-%d",
              date: {
                  "$toDate": "$raised_date"
              }
          }
        }: {
            $in: ["2019-05-13"]
        }
    }
}, {
    "$group": {
        "_id": {
            "$dateToString": {
                format: "%Y-%m-%d",
                date: {
                    "$toDate": "$raised_date"
                }
            }
        },
        amount_total: {
            $sum: "$amount"
        }
    }
}])  

Я пока не много работал над mongodb. Просто выясняю это.

Любая помощь приветствуется.

Ответы [ 3 ]

1 голос
/ 11 марта 2020

Вам нужно запустить $match перед группировкой, MongoDB может применить индекс, если вы определили для поля raised_date. После того как вы измените свои данные, индексы не могут быть применены.

Попробуйте это:

db.transactions.aggregate([
  {
    $match: {
      $or: [
        {
          raised_date: {
            $gte: ISODate("2019-01-05T00:00:00Z"),
            $lte: ISODate("2019-01-05T23:59:59Z")
          }
        },
        {
          raised_date: {
            $gte: ISODate("2019-05-13T00:00:00Z"),
            $lte: ISODate("2019-05-13T23:59:59Z")
          }
        }
      ]
    }
  },
  {
    "$group": {
      "_id": {
        "$dateToString": {
          format: "%Y-%m-%d",
          date: {
            "$toDate": "$raised_date"
          }
        }
      },
      amount_total: {
        $sum: "$amount"
      }
    }
  }
])

MongoPlayground

Примечание: Фильтрация по raised_date преобразование даты в строку должно соответствовать оператору $expr, например:

db.transactions.aggregate([
  {
    "$match": {
      $expr: {
        $in: [
          {
            "$dateToString": {
              format: "%Y-%m-%d",
              date: {
                "$toDate": "$raised_date"
              }
            }
          },
          [
            "2019-05-13", "2019-01-05"
          ]
        ]
      }
    }
  },
  {
    "$group": {
      "_id": {
        "$dateToString": {
          format: "%Y-%m-%d",
          date: {
            "$toDate": "$raised_date"
          }
        }
      },
      amount_total: {
        $sum: "$amount"
      }
    }
  }
])

MongoPlayground

1 голос
/ 11 марта 2020

Я использовал проект, чтобы преобразовать временные метки в даты, а затем отфильтровать их со списком дат с последующей агрегацией.

[{
    $project: {
        "raised_date": {
            "$dateToString": {
                format: "%Y-%m-%d",
                date: {
                    "$toDate": "$raised_date"
                }
            }
        },
        "amount": 1
    }
}, {
    $match: {
        raised_date: {
            $in: ["2019-05-13", "2019-01-05"]
        }
    }
}, {
    "$group": {
        "_id": "$raised_date",
        amount_total: {
            $sum: "$amount"
        }
    }
}]

Если есть лучший способ сделать это, опубликуйте его как ответ, который будет принят.

0 голосов
/ 11 марта 2020

после статистической функции вы должны использовать метод прогноза для вашего ответа

...