Javascript Mongodb聚合-今天按小时分组

Javascript Mongodb聚合-今天按小时分组,javascript,mongodb,mongoose,aggregation-framework,Javascript,Mongodb,Mongoose,Aggregation Framework,我想知道是否有人能帮我把聚合功能做好。我正试着数一数我的健康状况。我有一个访问表,其中保存了每次访问(从、到)的日期。此外,还保存了对某些服务的子访问 [{ "from": ISODate("2020-01-17T10:23:27.645Z"), "to": ISODate("2020-01-17T12:23:28.760Z"), "visits": [ { "from": ISODate("2020-01-17T10:23:27.646Z"), "t

我想知道是否有人能帮我把聚合功能做好。我正试着数一数我的健康状况。我有一个访问表,其中保存了每次访问(从、到)的日期。此外,还保存了对某些服务的子访问

[{
  "from": ISODate("2020-01-17T10:23:27.645Z"),
  "to": ISODate("2020-01-17T12:23:28.760Z"),
  "visits": [
    {
      "from": ISODate("2020-01-17T10:23:27.646Z"),
      "to": ISODate("2020-01-17T10:30:28.760Z"),
      "service": ObjectId("5e05f17d6b7f7920d4a62403")
    },
    {
      "from": ISODate("2020-01-17T10:30:29.760Z"),
      "to": ISODate("2020-01-17T12:23:28.760Z"),
      "service": ObjectId("5d05f17dt57f7920d4a62404")
    }
  ],
  ...
},
{
  "from": ISODate("2020-01-17T10:40:00.000Z"),
  "to": ISODate("2020-01-17T11:30:28.760Z"),
  "visits": [
    {
      "from": ISODate("2020-01-17T10:40:00.000Z"),
      "to": ISODate("2020-01-17T11:30:28.760Z"),
      "service": ObjectId("h505f17s6b2f7920d4a6295y")
    }
  ],
  ...
}
]
我想从00:00开始计算今天的结果,如果当前时间是13:35,那么直到13:00,如:

[{
  'date': '2020-01-18T00:00:0.000Z'
  'visits': 0
},
{
  'date': '2020-01-18T00:00:0.000Z'
  'visits': 0
},
{
  'date': '2020-01-18T00:00:0.000Z'
  'visits': 0
},
{
  'date': '2020-01-18T01:00:0.000Z'
  'visits': 0
},
{
  'date': '2020-01-18T02:00:0.000Z'
  'visits': 0
},
{
  'date': '2020-01-18T03:00:0.000Z'
  'visits': 0
},
{
  'date': '2020-01-18T04:00:0.000Z'
  'visits': 0
},
{
  'date': '2020-01-18T05:00:0.000Z'
  'visits': 0
},
{
  'date': '2020-01-18T06:00:0.000Z'
  'visits': 0
},
{
  'date': '2020-01-18T07:00:0.000Z'
  'visits': 0
},
{
  'date': '2020-01-18T08:00:0.000Z'
  'visits': 0
},
{
  'date': '2020-01-18T09:00:0.000Z'
  'visits': 0
},
{
  'date': '2020-01-18T010:00:0.000Z'
  'visits': 2
},
{
  'date': '2020-01-18T11:00:0.000Z'
  'visits': 2
},
{
  'date': '2020-01-18T12:00:0.000Z'
  'visits': 1
},
{
  'date': '2020-01-18T13:00:0.000Z'
  'visits': 0
}]
尝试了太多的例子,但没有任何效果,请帮助

解释
  • 如果我们现在使用
    $$NOW
    ,我们将获得当前日期。如果手动设置当前日期,
    今天
    下一天
    ,MongoDB聚合将限制所需的值

  • 现在,我们用
    $range
    操作符创建数组,计算从
    今天(yyyy-MM-dd 00:00:00)-
    当前日期(yyyy-MM-dd 13:35:00)~13小时开始的时间

  • 我们将间隔展平并应用过滤

  • 您可以使用以下查询:

    db.collection.aggregate([
      {
        $addFields: {
          nextDay: {
            $add: [
              {
                $dateFromString: {
                  dateString: {
                    $substr: [
                      {
                        $toString: "$$NOW"
                      },
                      0,
                      10
                    ]
                  },
                  format: "%Y-%m-%d"
                }
              },
              {
                $multiply: [
                  24,
                  60,
                  60,
                  1000
                ]
              }
            ]
          },
          today: {
            $dateFromString: {
              dateString: {
                $substr: [
                  {
                    $toString: "$$NOW"
                  },
                  0,
                  10
                ]
              },
              format: "%Y-%m-%d"
            }
          },
          currDate: {
            $dateFromString: {
              dateString: {
                $substr: [
                  {
                    $toString: "$$NOW"
                  },
                  0,
                  13
                ]
              },
              format: "%Y-%m-%dT%H",
              timezone: "-01"
            }
          }
        }
      },
      {
        $addFields: {
          interval: {
            $range: [
              0,
              {
                $add: [
                  {
                    $divide: [
                      {
                        $subtract: [
                          "$currDate",
                          "$today"
                        ]
                      },
                      {
                        $multiply: [
                          60,
                          60,
                          1000
                        ]
                      }
                    ]
                  },
                  1
                ]
              },
              1
            ]
          }
        }
      },
      {
        $unwind: "$interval"
      },
      {
        $addFields: {
          date: {
            $add: [
              "$today",
              {
                $multiply: [
                  "$interval",
                  60,
                  60,
                  1000
                ]
              }
            ]
          },
          nextHour: {
            $add: [
              "$today",
              {
                $multiply: [
                  {
                    $add: [
                      "$interval",
                      1
                    ]
                  },
                  60,
                  60,
                  1000
                ]
              }
            ]
          }
        }
      },
      {
        $project: {
          _id: 0,
          date: 1,
          today: 1,
          nextDay: 1,
          visits: {
            $reduce: {
              input: "$visits",
              initialValue: 0,
              in: {
                $add: [
                  "$$value",
                  {
                    $cond: [
                      {
                        $or: [
                          {
                            $and: [
                              {
                                $gte: [
                                  "$$this.from",
                                  "$date"
                                ]
                              },
                              {
                                $lte: [
                                  "$$this.from",
                                  "$nextHour"
                                ]
                              }
                            ]
                          },
                          {
                            $and: [
                              {
                                $lte: [
                                  "$date",
                                  "$$this.to"
                                ]
                              },
                              {
                                $gte: [
                                  "$date",
                                  "$$this.from"
                                ]
                              }
                            ]
                          }
                        ]
                      },
                      1,
                      0
                    ]
                  }
                ]
              }
            }
          }
        }
      },
      {
        $match: {
          $expr: {
            $and: [
              {
                $gte: [
                  "$date",
                  "$today"
                ]
              },
              {
                $lte: [
                  "$date",
                  "$nextDay"
                ]
              },
    
            ]
          }
        }
      },
      {
        $group: {
          _id: "$date",
          visits: {
            $sum: "$visits"
          }
        }
      },
      {
        $sort: {
          _id: 1
        }
      }
    ])
    

    对于JS安装程序,请单击


    如果您想要更优雅的方式,您可以尝试解决方案

    我们可以从javascript变量中使用startDate和endDate吗?当然可以。设置
    currDate
    nextDay
    今天的值查看确保您已复制粘贴了我的codeSure的最新版本,谢谢您的帮助。现在我还有最后一个问题,那就是我的体能负担。比如,如果我的访问时间是10:00到12:30,我需要显示10:00时1次访问,11:00时1次访问,12:00时也1次访问。我怎样才能达到这个逻辑?