MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Compter en fonction de la condition et diviser par le nombre d'enregistrements pour l'intervalle de temps

Si je comprends votre problème, voici une solution en utilisant $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"
                  ]
                }
              ]
            }
          },
          "%"
        ]
      }
    }
  }
])

Le résultat sera

[
  {
    "_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
  }
]