按天对文档分组并在MongoDB聚合管道中保留空组?

omvjsjqw  于 2023-03-17  发布在  Go
关注(0)|答案(1)|浏览(163)

我想知道在过去90天内每天创建了多少个文档。但是,我还想包括空匹配项,因此,如果没有文档与查询匹配,文档仍将包括在结果中,计数为0。
这是我的聚合管道的一部分,按天对文档进行分组:

[{
    $match: {
        createdAt: {
            $gte: new Date((new Date().getTime() - (90 * 24 * 60 * 60 * 1000)))
        }
    }
}, {
    $group: {
        _id: {
            $dateToString: {
                format: "%Y-%m-%d",
                date: "$createdAt"
            }
        },
        count: { $sum: 1 },
    }
}, {
    $project: {
        _id: 0,
        date: "$_id",
        count: 1,
    }
}]

示例结果如下:

[{
    count: 1,
    date: "2023-03-10"
}, {
    count: 5,
    date: "2023-03-07"
}]

但是,如果90天,我希望包括所有组,如果没有匹配项,则包括事件。例如:

[{
    count: 0,
    date: "2023-03-11"
}, {
    count: 2,
    date: "2023-03-12"
}, {
    count: 0,
    date: "2023-03-13"
}, /* All 90 days */ ]

我试过使用$bucket$bucketAuto操作符,但是这些操作符,尽管名称如此,似乎并不适合实现这一点。

3pmvbmvn

3pmvbmvn1#

首先使用$range生成过去90天的偏移数组。然后使用$map$dateAdd获取过去90天的日期。使用仅日期比较执行self $lookup以获取属于该日期的记录。

db.collection.aggregate([
  {
    $limit: 1
  },
  {
    "$project": {
      offset: {
        "$range": [
          -90,
          0
        ]
      }
    }
  },
  {
    $project: {
      _id: 1,
      date: {
        "$map": {
          "input": "$offset",
          "as": "o",
          "in": {
            $dateTrunc: {
              date: {
                "$dateAdd": {
                  "startDate": "$$NOW",
                  "unit": "day",
                  "amount": "$$o"
                }
              },
              unit: "day"
            }
          }
        }
      }
    }
  },
  {
    "$unwind": "$date"
  },
  {
    "$lookup": {
      "from": "collection",
      "let": {
        "dt": "$date"
      },
      "pipeline": [
        {
          "$match": {
            $expr: {
              $eq: [
                {
                  "$dateTrunc": {
                    date: "$key",
                    unit: "day"
                  }
                },
                "$$dt"
              ]
            }
          }
        },
        {
          "$count": "cnt"
        }
      ],
      "as": "records"
    }
  },
  {
    $project: {
      _id: 0,
      date: 1,
      count: {
        $ifNull: [
          {
            $first: "$records.cnt"
          },
          0
        ]
      }
    }
  }
])

Mongo Playground

相关问题