【问题标题】:Mongo DB query for count with conditionMongodb查询有条件的计数
【发布时间】:2022-11-09 03:58:27
【问题描述】:

我在 MongoDB 4.2 版的“部署”集合中存储了以下文档。

我想按 productId 并在一系列日期之间实现以下结果组。

我已经使用这个查询实现了执行时间。

    db.getCollection('Deployments').aggregate([
{
    $match : {$and:[{ "startedAt": { $gte: new ISODate("2021-10-01") } }, 
                   { "startedAt": { $lte: new ISODate("2021-11-17") } }]}
  },
  {
      $group : {
          _id:"$productId",
          count: { $sum: 1 },
          minExecutionTime:
                    {
                        
                       $min:
                          {
                             $divide:[{$subtract:["$completedAt", "$startedAt"]}, 1000 * 60]
                                
                           }
                    },
          maxExecutionTime:
                    {
                       $max:
                          {
                             $divide:[{$subtract:["$completedAt", "$startedAt"]}, 1000 * 60]
                                
                           }
                    },
          avgExecutionTime:
                    {
                       $avg:
                          {
                             $divide:[{$subtract:["$completedAt", "$startedAt"]}, 1000 * 60]
                                
                           }
                    }
          }
      
      }
  ])
  1. 请帮我把计数添加到这个查询中?
  2. 如何将执行时间截断到小数点后 2 位?
  3. 如果对此查询有任何优化,请提出建议。

    文件:

    [
      {
        "productId": 1,
        "deploymentStatus": "Succeeded",
        "startedAt": ISODate("2021-01-21T14:00:19.782Z"),
        "completedAt": ISODate("2021-01-21T14:03:55.789Z")
      },
      {
        "productId": 2,
        "deploymentStatus": "Failed",
        "startedAt": ISODate("2021-01-21T15:00:19.782Z"),
        "completedAt": ISODate("2021-01-21T15:03:55.789Z")
      },
      {
        "productId": 3,
        "deploymentStatus": "Cancelled",
        "startedAt": ISODate("2021-01-21T16:00:19.782Z"),
        "completedAt": ISODate("2021-01-21T16:03:55.789Z")
      },
      {
        "productId": 1,
        "deploymentStatus": "Failed",
        "startedAt": ISODate("2021-01-21T17:00:19.782Z"),
        "completedAt": ISODate("2021-01-21T17:03:55.789Z")
      },
      {
        "productId": 2,
        "deploymentStatus": "Failed",
        "startedAt": ISODate("2021-01-21T18:00:19.782Z"),
        "completedAt": ISODate("2021-01-21T18:03:55.789Z")
      },
      {
        "productId": 3,
        "deploymentStatus": "Succeeded",
        "startedAt": ISODate("2021-01-21T19:00:19.782Z"),
        "completedAt": ISODate("2021-01-21T19:03:55.789Z")
      },
      {
        "productId": 1,
        "deploymentStatus": "Cancelled",
        "startedAt": ISODate("2021-01-21T20:00:19.782Z"),
        "completedAt": ISODate("2021-01-21T20:03:55.789Z")
      },
      {
        "productId": 2,
        "deploymentStatus": "Failed",
        "startedAt": ISODate("2021-01-21T21:00:19.782Z"),
        "completedAt": ISODate("2021-01-21T21:03:55.789Z")
      },
      {
        "productId": 3,
        "deploymentStatus": "Succeeded",
        "startedAt": ISODate("2021-01-21T22:00:19.782Z"),
        "completedAt": ISODate("2021-01-21T22:03:55.789Z")
      }
    ]
    

    Mongo Playground

【问题讨论】:

  • 如果您可以以文档形式而不是图像形式提供示例数据集,将会很有帮助。
  • 以文档形式添加数据集,请验证。
  • 你可以用你的示例添加一个游乐场吗?
  • 还添加了 mongo 游乐场链接 - mongoplayground.net/p/llobFoovRNN

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:

您的聚合实际上是在正确的轨道上。对于您的 3 个问题:

请问有什么帮助可以将计数添加到此查询中吗?

只需使用$cond 将计数分成 3 个条件计数

如何将执行时间截断到小数点后 2 位?

使用$round

如果对此查询有任何优化,请提出建议。

我做了一个小调整,以分钟为单位预先计算持续时间,而不是在$group 阶段再次计算它们

db.collection.aggregate([
  {
    $match: {
      $and: [
        {
          "startedAt": {
            $gte: ISODate("2021-01-21")
          }
        },
        {
          "startedAt": {
            $lte: ISODate("2021-01-22")
          }
        }
      ]
    }
  },
  {
    "$addFields": {
      "durationInMin": {
        $round: [
          {
            $divide: [
              {
                $subtract: [
                  "$completedAt",
                  "$startedAt"
                ]
              },
              60000
            ]
          },
          2
        ]
      }
    }
  },
  {
    $group: {
      _id: "$productId",
      SucceedCount: {
        $sum: {
          "$cond": {
            "if": {
              $eq: [
                "$deploymentStatus",
                "Succeeded"
              ]
            },
            "then": 1,
            "else": 0
          }
        }
      },
      FailedCount: {
        $sum: {
          "$cond": {
            "if": {
              $eq: [
                "$deploymentStatus",
                "Failed"
              ]
            },
            "then": 1,
            "else": 0
          }
        }
      },
      CancelledCount: {
        $sum: {
          "$cond": {
            "if": {
              $eq: [
                "$deploymentStatus",
                "Cancelled"
              ]
            },
            "then": 1,
            "else": 0
          }
        }
      },
      minExecutionTime: {
        $min: "$durationInMin"
      },
      maxExecutionTime: {
        $max: "$durationInMin"
      },
      avgExecutionTime: {
        $avg: "$durationInMin"
      }
    }
  }
])

这是Mongo playground 供您参考。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-25
    • 2019-06-14
    • 1970-01-01
    • 2022-07-07
    • 2021-01-11
    • 1970-01-01
    相关资源
    最近更新 更多