Mongo聚合:根据数组字段匹配条件对文档进行计数

时间:2020-05-14 11:23:49

标签: mongodb mongodb-query

我正在尝试使用聚合管道从mongo集合中收集一些统计信息,但似乎无法解决我的问题。

我有一些像这样的文件。

{
    _id: “36723678126”,
    dates: [ 2020-03-10T10:17:48.799Z, 2020-03-10T08:46:50.347Z, 2019-07-11T13:16:17.294Z ]
}

我要计算满足以下条件的文档数量

  • 过去30天内至少有一个日期
  • 60到30天前没有日期
  • 至少60天前的一个日期

非常感谢您的帮助! :)

1 个答案:

答案 0 :(得分:1)

这应该可以解决问题(https://mongoplayground.net/p/B3LbEo8UaHA):

测试数据

[
  {
    _id: 1,
    dates: [
      ISODate("2020-03-10T10:17:48.799Z"),
      ISODate("2020-03-10T08:46:50.347Z"),
      ISODate("2019-07-11T13:16:17.294Z")
    ]
  },
  {
    _id: 2,
    dates: [
      ISODate("2020-04-10T10:17:48.799Z"),
      ISODate("2020-05-10T08:46:50.347Z"),
      ISODate("2019-10-11T13:16:17.294Z")
    ]
  }
]

查询

db.collection.aggregate([
  // create the new fields based on the date rules and count occurences of array
  {
    $addFields: {
      "last_30_days": {
        $sum: {
          $map: {
            "input": "$dates",
            "as": "d",
            "in": {
              $cond: {
                "if": {
                  $lte: [
                    "$$d",
                    {
                      $subtract: [
                        "$$NOW",
                        2592000000 // 30 days
                      ]
                    }
                  ]
                },
                "then": 1,
                "else": 0
              }
            }
          }
        }
      },
      "between_30_60": {
        $sum: {
          $map: {
            "input": "$dates",
            "as": "d",
            "in": {
              $cond: {
                "if": {
                  $and: [
                    {
                      $lt: [
                        "$$d",
                        {
                          $subtract: [
                            "$$NOW",
                            2592000000 // days
                          ]
                        }
                      ]
                    },
                    {
                      $gt: [
                        "$$d",
                        {
                          $subtract: [
                            "$$NOW",
                            5184000000 // 60 days
                          ]
                        }
                      ]
                    }
                  ]
                },
                "then": 1,
                "else": 0
              }
            }
          }
        }
      },
      "last_60_days": {
        $sum: {
          $map: {
            "input": "$dates",
            "as": "d",
            "in": {
              $cond: {
                "if": {
                  $lte: [
                    "$$d",
                    {
                      $subtract: [
                        "$$NOW",
                        5184000000
                      ]
                    }
                  ]
                },
                "then": 1,
                "else": 0
              }
            }
          }
        }
      }
    }
  },
  // find which document meet the conditions (1 for true, 0 for false)
  {
    $project: {
      "meet_conditions": {
        $cond: {
          "if": {
            $and: [
              {
                $gt: [
                  "$last_30_days",  // at least one occurence
                  0
                ]
              },
              {
                $eq: [
                  "$between_30_60",  // no occurences
                  0
                ]
              },
              {
                $gt: [
                  "last_60_days",  // at least one occurence
                  0
                ]
              }
            ]
          },
          "then": 1,
          "else": 0
        }
      }
    }
  },
  // count documents, summing the meet_conditions field (because they are 0 or 1)
  {
    $group: {
      _id: null,
      count: {
        $sum: "$meet_conditions"
      }
    }
  }
])

结果

[
  {
    "_id": null,
    "count": 1
  }
]

因此在上面的示例中,只有一个文档可以满足您的条件。

肥胖:要计算所需的工作天数(粗体数字是您想要的工作天):

1 * 1000 * 60 * 60 * 24 * 30 = 2592000000ms = 30天

1 * 1000 * 60 * 60 * 24 * 60 = 5184000000ms = 60天