MongoDb Aggregate, найти дубликаты записей в течение 7 дней - PullRequest
0 голосов
/ 24 февраля 2020

Мне нужно создать чек для этого варианта использования -

Дублирующийся чек платежа

• Для всех транзакций одинаковая сумма с тем же номером счета за последние 7 дней.

Я не использовал mongoDb, так как мне было бы проще написать sql

Это то, что я пытаюсь без 7-дневной части

db.transactiondetails.aggregate({$group: {"_id":{"account_number":"$account_number","amount":"$amount"},"count": { $sum: 1 }}}) 

Где я получу что-то вроде этого:

{ "_id" : { "account_number" : "xxxxxxxy", "amount" : 19760 }, "count" : 2 }
{ "_id" : { "account_number" : "xxxxzzzz", "amount" : 20140 }, "count" : 2 }
...

У меня есть created_at и updated_at, которые являются полями даты, я использую updated_at для дубликатов

, например:

"created_at" : ISODate("2019-01-07T15:40:53.683Z"),
"updated_at" : ISODate("2019-01-09T06:48:44.839Z"), 

В sql мы можем создать группы по 7 дней, для каждой даты будет указана дата начала плюс 7 дней, в которые нам нужно найти дубликаты.

Это 7-дневные группы, в которых мне нужно найти дубликаты.

Любая помощь, как go об этом будет оценена.

1 Ответ

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

Проверьте, соответствует ли это вашим требованиям:

Объяснение

  1. Мы сортируем документы (я полагаю, у вас есть индексы). Нам нужно это для итерации массива в следующих шагах.
  2. Мы группируем по account_number + amount и создаем массивы (data, tmp) с документами
  3. Мы $unwind (сгладить) массив tmp для вычисления количества прошедших дней для элемента i для элемента i + 1 - n
  4. Мы считаем, сколько дубликатов у нас на разные даты
  5. Пропустить все counts = 0

db.transactiondetails.aggregate([
  {
    $sort: {
      account_number: 1,
      amount: 1,
      updated_at: 1
    }
  },
  {
    $group: {
      "_id": {
        "account_number": "$account_number",
        "amount": "$amount"
      },
      "data": {
        $push: "$$ROOT"
      },
      "tmp": {
        $push: "$$ROOT"
      }
    }
  },
  {
    $unwind: "$tmp"
  },
  {
    $project: {
      _id: {
        account_number: "$_id.account_number",
        amount: "$_id.amount",
        updated_at: "$tmp.updated_at"
      },
      data: {
        $map: {
          input: {
            $slice: [
              "$data",
              {
                $add: [
                  {
                    $indexOfArray: [
                      "$data",
                      "$tmp"
                    ]
                  },
                  1
                ]
              },
              {
                $size: "$data"
              }
            ]
          },
          in: {
            "_id": "$$this._id",
            "account_number": "$$this.account_number",
            "amount": "$$this.amount",
            "created_at": "$$this.created_at",
            "updated_at": "$$this.updated_at",
            "days": {
              $divide: [
                {
                  $subtract: [
                    "$$this.updated_at",
                    "$tmp.updated_at"
                  ]
                },
                {
                  $multiply: [
                    24,
                    60,
                    60,
                    1000
                  ]
                }
              ]
            }
          }
        }
      }
    }
  },
  {
    $project: {
      count: {
        $size: {
          $filter: {
            input: "$data",
            cond: {
              $lte: [
                "$$this.days",
                7
              ]
            }
          }
        }
      }
    }
  },
  {
    $match: {
      "count": {
        $gt: 0
      }
    }
  }
])

MongoPlayground

...