【问题标题】:MongoDb Aggregate , find duplicate records within 7 daysMongoDb Aggregate ,7天内找到重复记录
【发布时间】:2020-06-07 19:19:39
【问题描述】:

我必须为这个用例创建一个检查 -

重复付款支票

• 在过去 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_atupdated_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 天的小组,我需要在其中找到重复项。

我们将不胜感激。

【问题讨论】:

  • 分组方式:account_number + amount + diff(updated_at - created_at) < 7 days 解决了您的用例?
  • @Valijon 我认为答案是否定的,因为我们需要解决可能的递归问题,他没有提到精确定义重复的内容,例如,如果我们有 3 个相隔 5 天的文档,每个文档相同帐户和金额是第 3 次重复第 1 次吗? 2cd的副本?它不是重复的吗?目前还不清楚。
  • @Valijon :我想要这样的东西来聚合从当前记录起 7 天的日期范围内的记录,这些记录具有相似的金额和 account_number {$gte : {$subtract : ["$updated_at" , (7 * 24 * 60 * 60 * 1000)]} , $other_updated_ats }
  • 我在 2017-2018 年的 MongoDB World 聚合演示中有一个非常相似的例子,代码在这里:github.com/asya999/mdbw17/blob/master/networkLogins.js
  • @AsyaKamsky 是的Find logins from different IPs within 10 minutes over specified time period ,好像是一样的情况。

标签: mongodb duplicates aggregation-framework


【解决方案1】:

检查这是否符合您的要求:

说明

  1. 我们对文档进行排序(我假设您有索引)。我们需要它在接下来的步骤中迭代数组。
  2. 我们按account_number + amount 分组,并使用文档创建数组(datatmp
  3. 我们 $unwind (flatten) tmp 数组来计算从 itemi 到 itemi+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

【讨论】:

  • 看起来不错。一个月以来,我每天都运行 38 个查询,即过去 7 天到今天之间的每一天查询(如果有任何重复)。这似乎也不错。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-15
  • 2015-01-15
  • 1970-01-01
  • 2021-02-24
  • 1970-01-01
  • 2020-02-07
  • 2013-07-14
相关资源
最近更新 更多