MongoDB: Calculate dwell time between every status value change

后端 未结 3 1623
别跟我提以往
别跟我提以往 2020-11-29 14:12

I want to find out the dwell time between every presenceStatus change.

Example collection -

   /* 1 */

{
    \"_id\" : ObjectId(\"5e4889a7c7959f6a         


        
3条回答
  •  [愿得一人]
    2020-11-29 14:46

    Check if this solution meets your requirements.

    Explanation

    1. We join over the same collection. So for each item i we take item i+1. This method gives us where presenceStatus has been changed.
    2. We filter documenti i+1 pairs where presenceStatus is 0 - 1 or 1 - 0.
    3. We group them into single data array.
    4. Now we iterate over data by 2 steps (i=0;i and take updatedAt value.
        var occupiedTime = data[i].tmp.updatedAt
        var vacantTime   = data[i+1].tmp.updatedAt
    
    1. We flatten calculated values and restore original document structure.

    db.collection.aggregate([
      {
        $lookup: {
          from: "collection",
          let: {
            root_id: "$_id"
          },
          pipeline: [
            {
              $match: {
                $expr: {
                  $gt: [
                    "$_id",
                    "$$root_id"
                  ]
                }
              }
            },
            {
              $limit: 1
            }
          ],
          as: "tmp"
        }
      },
      {
        $match: {
          $or: [
            {
              "presenceStatus": 1,
              "tmp.presenceStatus": 0
            },
            {
              "presenceStatus": 0,
              "tmp.presenceStatus": 1
            }
          ]
        }
      },
      {
        $group: {
          _id: null,
          data: {
            $push: {
              $mergeObjects: [
                "$$ROOT",
                {
                  tmp: {
                    $arrayElemAt: [
                      "$tmp",
                      0
                    ]
                  }
                }
              ]
            }
          }
        }
      },
      {
        $addFields: {
          data: {
            $map: {
              input: {
                $range: [
                  0,
                  {
                    $size: "$data"
                  },
                  2
                ]
              },
              as: "idx",
              in: {
                "occupiedTime": {
                  $arrayElemAt: [
                    "$data.tmp.updatedAt",
                    {
                      $cond: [
                        {
                          $eq: [
                            {
                              $arrayElemAt: [
                                "$data.tmp.presenceStatus",
                                "$$idx"
                              ]
                            },
                            1
                          ]
                        },
                        "$$idx",
                        {
                          $add: [
                            "$$idx",
                            1
                          ]
                        }
                      ]
                    }
                  ]
                },
                "vacantTime": {
                  $arrayElemAt: [
                    "$data.tmp.updatedAt",
                    {
                      $cond: [
                        {
                          $eq: [
                            {
                              $arrayElemAt: [
                                "$data.tmp.presenceStatus",
                                "$$idx"
                              ]
                            },
                            0
                          ]
                        },
                        "$$idx",
                        {
                          $add: [
                            "$$idx",
                            1
                          ]
                        }
                      ]
                    }
                  ]
                },
                "created": {
                  $arrayElemAt: [
                    "$data.tmp.createdAt",
                    "$$idx"
                  ]
                },
                "_id": {
                  $arrayElemAt: [
                    "$data.tmp._id",
                    "$$idx"
                  ]
                },
                "__v": 0
              }
            }
          }
        }
      },
      {
        $unwind: "$data"
      },
      {
        $replaceRoot: {
          newRoot: "$data"
        }
      },
      {
        $addFields: {
          "dwellTime": {
            $dateToString: {
              date: {
                $toDate: {
                  $subtract: [
                    "$vacantTime",
                    "$occupiedTime"
                  ]
                }
              },
              format: "%H-%M-%S"
            }
          }
        }
      }
    ])
    

    MongoPlayground

提交回复
热议问题