Count based on Condition and divide by # of records for time interval

给你一囗甜甜゛ 提交于 2020-05-24 05:37:05

问题


I have mongoplayground example ready for this question.

https://mongoplayground.net/p/m_G-yBuX6uk

Currently it shows data aggregation based on 15min time interval on some fields. There is a field called "presenceStatus" which has value either 0 or 1.

Current result

 {
        "accountId": ObjectId("5e1fe45cd05bfb0cc549297d"),
        "applicationNumber": 30,
        "area": "area2",
        "avgZoneCountNumber": 0,
        "avgZoneCountNumberInstant": 0,
        "buildingId": ObjectId("5e1fe5e3d05bfb0cc5494146"),
        "createdAt": ISODate("1970-01-01T00:00:00Z"),
        "dateHour": "2020-03-19T18:15:00.000Z",
        "deviceId": ObjectId("5e1fe7a9d05bfb0cc5495cdf"),
        "gatewayId": ObjectId("5e1fe651d05bfb0cc54947f0"),
        "serialNumber": "129300000012",
        "spaceType": null
      },

Expected: I need to find occupancyRate for each time interval.

For 15min interval, formula is count presenceStatus = 1 and divide by total records for that time frame. Expected value should be in % format as shown below for occupancyRate field.

Expected result:

{
    "accountId": ObjectId("5e1fe45cd05bfb0cc549297d"),
    "applicationNumber": 30,
    "area": "area2",
    "avgZoneCountNumber": 0,
    "avgZoneCountNumberInstant": 0,
    "buildingId": ObjectId("5e1fe5e3d05bfb0cc5494146"),
    "createdAt": ISODate("1970-01-01T00:00:00Z"),
    "dateHour": "2020-03-19T18:15:00.000Z",
    "deviceId": ObjectId("5e1fe7a9d05bfb0cc5495cdf"),
    "gatewayId": ObjectId("5e1fe651d05bfb0cc54947f0"),
    "serialNumber": "129300000012",
    "spaceType": null,
    "occupancyRate": 80%
  },

In Mongo playground example(totalPresent field), I have tried to display count for presenceStatus= 1 but it shows as 0.

Your help is appreciated.


回答1:


If I understand your problem, here is a solution using $group :

db.sensingresults.aggregate([
  {
    "$lookup": {
      "from": "accounts",
      "localField": "accountId",
      "foreignField": "_id",
      "as": "accountInfo"
    }
  },
  {
    "$unwind": "$accountInfo"
  },
  {
    $addFields: {
      "dateHour": {
        "$dateToString": {
          "format": "%Y-%m-%dT%H",
          "date": "$updatedAt"
        }
      },
      "minuteBucket": {
        "$trunc": {
          "$divide": [
            {
              "$minute": "$updatedAt"
            },
            15.0
          ]
        }
      },
      "device": {
        "$let": {
          "vars": {
            "building": {
              "$arrayElemAt": [
                {
                  "$filter": {
                    "input": "$accountInfo.buildings",
                    "cond": {
                      "$eq": [
                        "$$this._id",
                        "$buildingId"
                      ]
                    }
                  }
                },
                0
              ]
            }
          },
          "in": {
            "$let": {
              "vars": {
                "gateway": {
                  "$arrayElemAt": [
                    {
                      "$filter": {
                        "input": "$$building.gateways",
                        "cond": {
                          "$eq": [
                            "$$this._id",
                            "$gatewayId"
                          ]
                        }
                      }
                    },
                    0
                  ]
                }
              },
              "in": {
                "$arrayElemAt": [
                  {
                    "$filter": {
                      "input": "$$gateway.devices",
                      "cond": {
                        "$eq": [
                          "$$this._id",
                          "$deviceId"
                        ]
                      }
                    }
                  },
                  0
                ]
              }
            }
          }
        }
      }
    }
  },
  {
    $group: {
      _id: {
        area: "$device.area",
        applicationNumber: "$device.applicationNumber",
        accountId: "$accountId",
        dateHour: "$dateHour",
        minuteBucket: "$minuteBucket",
        buildingId: "$buildingId"
      },
      avgZoneCountNumberInstant: {
        $avg: "$zoneCountNumberInstant"
      },
      avgZoneCountNumber: {
        $avg: "$zoneCountNumber"
      },
      total: {
        $sum: 1
      },
      "spaceType": {
        "$first": "$device.spaceType"
      },
      presences: {
        $sum: "$presenceStatus"
      }
    }
  },
  {
    $addFields: {
      occupancyRate: {
        $concat: [
          {
            $toString: {
              $multiply: [
                100,
                {
                  $divide: [
                    "$presences",
                    "$total"
                  ]
                }
              ]
            }
          },
          "%"
        ]
      }
    }
  }
])

The result will be

[
  {
    "_id": {
      "accountId": ObjectId("5e1fe45cd05bfb0cc549297d"),
      "applicationNumber": 30,
      "area": "area2",
      "buildingId": ObjectId("5e1fe5e3d05bfb0cc5494146"),
      "dateHour": "2020-03-19T18",
      "minuteBucket": 1
    },
    "avgZoneCountNumber": 0,
    "avgZoneCountNumberInstant": 0,
    "occupancyRate": "0%",
    "presences": 0,
    "spaceType": null,
    "total": 1
  },
  {
    "_id": {
      "accountId": ObjectId("5e1fe45cd05bfb0cc549297d"),
      "buildingId": ObjectId("5e1fe5e3d05bfb0cc5494146"),
      "dateHour": "2020-03-19T18",
      "minuteBucket": 1
    },
    "avgZoneCountNumber": 0,
    "avgZoneCountNumberInstant": 0,
    "occupancyRate": "0%",
    "presences": 0,
    "spaceType": null,
    "total": 2
  },
  {
    "_id": {
      "accountId": ObjectId("5e1fe45cd05bfb0cc549297d"),
      "buildingId": ObjectId("5e1fe5e3d05bfb0cc5494146"),
      "dateHour": "2020-03-20T18",
      "minuteBucket": 1
    },
    "avgZoneCountNumber": 0.5,
    "avgZoneCountNumberInstant": 0,
    "occupancyRate": "100%",
    "presences": 2,
    "spaceType": null,
    "total": 2
  }
]


来源:https://stackoverflow.com/questions/61145727/count-based-on-condition-and-divide-by-of-records-for-time-interval

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!