【问题标题】:Mongodb find the Consecutive Failure CountMongodb查找连续失败计数
【发布时间】:2022-01-01 23:49:26
【问题描述】:

我有一个这样的数据集:

{
    ip: 1.1.1.1,
    process: 123,
    type: failure,
    date: 2021-04-01
},
{
    ip: 1.1.1.2,
    process: 124,
    type: failure,
    date: 2021-03-01
},
{
    ip: 1.1.1.1,
    process: 123,
    type: failure,
    date: 2021-02-01
},
{
    ip: 1.1.1.1,
    process: 123,
    type: success,
    date: 2021-01-01
}

如何获取给定 IP 地址和进程的连续失败计数?例如,给定上面的数据集,如果我要检查 ip 1.1.1.1 在最后一次成功之前对进程 123 失败了多少次,我应该得到 2。但是,如果成功记录是最后一条记录,那么我应该得到 0。

到目前为止我所拥有的是:

activityLog.find([
  {
    $match: {
      ip: "1.1.1.1",
      process: "123"
    },
  },
  {
    $sort: {
      date: -1,
    },
  },
  {
    $limit: 10,
  },
  {
    $project: {
      _id: 0,
      type: 1,
    },
  },
]);

这给了我所有类型的列表 - 排序和匹配

【问题讨论】:

    标签: mongodb mongoose mongodb-query


    【解决方案1】:

    您可以在聚合管道中执行以下操作:

    1. 查找之前的成功记录
    2. 进行自查以查找上一个成功记录之后的失败记录
    3. 计算第 2 步的查找次数
    db.collection.aggregate([
      {
        $match: {
          ip: "1.1.1.1",
          process: "123",
          type: "success"
        }
      },
      {
        "$sort": {
          date: -1
        }
      },
      {
        $limit: 1
      },
      {
        "$lookup": {
          "from": "collection",
          let: {
            ip: "$ip",
            process: "$process",
            date: "$date"
          },
          pipeline: [
            {
              $match: {
                $expr: {
                  $and: [
                    {
                      $eq: [
                        "$ip",
                        "$$ip"
                      ]
                    },
                    {
                      $eq: [
                        "$process",
                        "$$process"
                      ]
                    },
                    {
                      $lt: [
                        "$date",
                        "$$date"
                      ]
                    },
                    {
                      $eq: [
                        "$type",
                        "success"
                      ]
                    }
                  ]
                }
              }
            },
            {
              $sort: {
                date: -1
              }
            },
            {
              $limit: 1
            }
          ],
          "as": "lastSuccess"
        }
      },
      {
        "$unwind": {
          path: "$lastSuccess",
          preserveNullAndEmptyArrays: true
        }
      },
      {
        "$lookup": {
          "from": "collection",
          let: {
            ip: "$ip",
            process: "$process",
            date: {
              $ifNull: [
                "$lastSuccess.date",
                ISODate("9999-12-31")
              ]
            }
          },
          pipeline: [
            {
              $match: {
                $expr: {
                  $and: [
                    {
                      $eq: [
                        "$ip",
                        "$$ip"
                      ]
                    },
                    {
                      $eq: [
                        "$process",
                        "$$process"
                      ]
                    },
                    {
                      $gte: [
                        "$date",
                        "$$date"
                      ]
                    },
                    {
                      $eq: [
                        "$type",
                        "failure"
                      ]
                    }
                  ]
                }
              }
            }
          ],
          "as": "previousFailures"
        }
      },
      {
        "$addFields": {
          "lastFailuresCount": {
            $size: "$previousFailures"
          }
        }
      }
    ])
    

    这里是Mongo playground 供您参考

    【讨论】:

    • 感谢@ray,但添加最新的成功事件似乎不会产生正确的结果。看看mongoplayground.net/p/scaI3u4t4Zn
    • @VishalRastogi 很抱歉这个错误。我已经更新了答案以使用默认的最大上次成功日期查找以前的失败,以便在您的最新测试数据集中不会有 2021-01-01 成功记录的其他错误匹配的失败记录
    猜你喜欢
    • 2019-02-16
    • 2019-10-30
    • 1970-01-01
    • 2021-11-16
    • 2017-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多