【问题标题】:MongoDB Aggregation Pipeline help (Convert MySQL to Mongo)MongoDB 聚合管道帮助(将 MySQL 转换为 Mongo)
【发布时间】:2021-10-31 01:17:57
【问题描述】:

我知道有人问过这些问题,而且我是 MongoDB 的新手,这意味着我正在苦苦挣扎。我正在使用指南针并试图找出这个聚合管道。简而言之,我需要得到按 id 分组的最大和最小时间戳之间的平均时间差。

预期的结果只是:avg_time: 234.00 或类似的。

等效的 MySQL 查询如下所示:

select SEC_TO_TIME(AVG(TIME_TO_SEC(TIMEDIFF(a.maxDate,a.minDate)))) FROM (select id, min(timestamp) as minDate, max(timestamp) as maxDate from counterHistory group by id) as a

数据集如下所示:

[{
  "_id": {
    "$oid": "617dce992743dd52bed811a6"
  },
  "dateStart": {
    "$date": "2021-10-30T23:00:41.056Z"
  },
  "dateEnd": {
    "$date": "2021-10-30T23:00:52.404Z"
  },
  "areas": {
    "c2acc5cc-9a7a-4406-8d91-79cb7f7ded70": {
      "color": "yellow",
      "type": "rightleft_bottomtop",
      "location": {
        "point1": {
          "x": 1397,
          "y": 702
        },
        "point2": {
          "x": 1808,
          "y": 645
        },
        "refResolution": {
          "w": 1920,
          "h": 969
        }
      },
      "computed": {
        "a": 0.15457277801631616,
        "b": -332.7843438566361,
        "lineBearings": [
          81.21317228796154,
          261.2131722879615
        ],
        "point1": {
          "x": 465.6666666666667,
          "y": -260.80495356037153
        },
        "point2": {
          "x": 602.6666666666666,
          "y": -239.62848297213623
        }
      },
      "name": "Right line start"
    },
    "56885eaf-9808-4b5e-b193-06b20e10c39d": {
      "color": "turquoise",
      "type": "rightleft_bottomtop",
      "location": {
        "point1": {
          "x": 770,
          "y": 411
        },
        "point2": {
          "x": 1085,
          "y": 360
        },
        "refResolution": {
          "w": 1920,
          "h": 969
        }
      },
      "computed": {
        "a": 0.18045112781954886,
        "b": -199.0092879256966,
        "lineBearings": [
          79.77099171264048,
          259.77099171264047
        ],
        "point1": {
          "x": 256.6666666666667,
          "y": -152.6934984520124
        },
        "point2": {
          "x": 361.6666666666667,
          "y": -133.74613003095976
        }
      },
      "name": "right lane end"
    }
  },
  "videoResolution": {
    "w": 640,
    "h": 360
  },
  "filename": "demo.mp4",
  "counterSummary": {
    "56885eaf-9808-4b5e-b193-06b20e10c39d": {
      "_total": 8,
      "car": 8
    },
    "c2acc5cc-9a7a-4406-8d91-79cb7f7ded70": {
      "_total": 8,
      "car": 7,
      "truck": 1
    }
  },
  "trackerSummary": {
    "totalItemsTracked": 64
  },
  "counterHistory": [
    {
      "frameId": 29,
      "timestamp": {
        "$date": "2021-10-30T23:00:42.694Z"
      },
      "area": "c2acc5cc-9a7a-4406-8d91-79cb7f7ded70",
      "name": "car",
      "id": 408,
      "bearing": 291.8014094863518,
      "countingDirection": "rightleft_bottomtop",
      "angleWithCountingLine": 30.588237198390278
    },
    {
      "frameId": 43,
      "timestamp": {
        "$date": "2021-10-30T23:00:43.619Z"
      },
      "area": "c2acc5cc-9a7a-4406-8d91-79cb7f7ded70",
      "name": "truck",
      "id": 457,
      "bearing": 293.1985905136482,
      "countingDirection": "rightleft_bottomtop",
      "angleWithCountingLine": 31.985418225686644
    },
    {
      "frameId": 50,
      "timestamp": {
        "$date": "2021-10-30T23:00:44.063Z"
      },
      "area": "56885eaf-9808-4b5e-b193-06b20e10c39d",
      "name": "car",
      "id": 421,
      "bearing": 303.69006752597977,
      "countingDirection": "rightleft_bottomtop",
      "angleWithCountingLine": 43.919075813339305
    },
    {
      "frameId": 63,
      "timestamp": {
        "$date": "2021-10-30T23:00:44.927Z"
      },
      "area": "c2acc5cc-9a7a-4406-8d91-79cb7f7ded70",
      "name": "car",
      "id": 458,
      "bearing": 293.6293777306568,
      "countingDirection": "rightleft_bottomtop",
      "angleWithCountingLine": 32.41620544269528
    },
    {
      "frameId": 65,
      "timestamp": {
        "$date": "2021-10-30T23:00:45.054Z"
      },
      "area": "56885eaf-9808-4b5e-b193-06b20e10c39d",
      "name": "car",
      "id": 464,
      "bearing": 284.03624346792645,
      "countingDirection": "rightleft_bottomtop",
      "angleWithCountingLine": 24.265251755286005
    },
    {
      "frameId": 78,
      "timestamp": {
        "$date": "2021-10-30T23:00:45.888Z"
      },
      "area": "c2acc5cc-9a7a-4406-8d91-79cb7f7ded70",
      "name": "car",
      "id": 469,
      "bearing": 303.69006752597977,
      "countingDirection": "rightleft_bottomtop",
      "angleWithCountingLine": 42.47689523801825
    },
    {
      "frameId": 86,
      "timestamp": {
        "$date": "2021-10-30T23:00:46.415Z"
      },
      "area": "56885eaf-9808-4b5e-b193-06b20e10c39d",
      "name": "car",
      "id": 427,
      "bearing": 354.28940686250036,
      "countingDirection": "rightleft_bottomtop",
      "angleWithCountingLine": 85.48158485014012
    },
    {
      "frameId": 122,
      "timestamp": {
        "$date": "2021-10-30T23:00:48.757Z"
      },
      "area": "c2acc5cc-9a7a-4406-8d91-79cb7f7ded70",
      "name": "car",
      "id": 479,
      "bearing": 296.565051177078,
      "countingDirection": "rightleft_bottomtop",
      "angleWithCountingLine": 35.35187888911645
    },
    {
      "frameId": 125,
      "timestamp": {
        "$date": "2021-10-30T23:00:48.946Z"
      },
      "area": "56885eaf-9808-4b5e-b193-06b20e10c39d",
      "name": "car",
      "id": 408,
      "bearing": 323.13010235415595,
      "countingDirection": "rightleft_bottomtop",
      "angleWithCountingLine": 63.359110641515514
    },
    {
      "frameId": 143,
      "timestamp": {
        "$date": "2021-10-30T23:00:50.143Z"
      },
      "area": "56885eaf-9808-4b5e-b193-06b20e10c39d",
      "name": "car",
      "id": 473,
      "bearing": 284.03624346792645,
      "countingDirection": "rightleft_bottomtop",
      "angleWithCountingLine": 24.265251755286005
    },
    {
      "frameId": 152,
      "timestamp": {
        "$date": "2021-10-30T23:00:50.716Z"
      },
      "area": "c2acc5cc-9a7a-4406-8d91-79cb7f7ded70",
      "name": "car",
      "id": 438,
      "bearing": 296.565051177078,
      "countingDirection": "rightleft_bottomtop",
      "angleWithCountingLine": 35.35187888911645
    },
    {
      "frameId": 160,
      "timestamp": {
        "$date": "2021-10-30T23:00:51.242Z"
      },
      "area": "56885eaf-9808-4b5e-b193-06b20e10c39d",
      "name": "car",
      "id": 455,
      "bearing": 45,
      "countingDirection": "rightleft_bottomtop",
      "angleWithCountingLine": 34.77099171264047
    },
    {
      "frameId": 174,
      "timestamp": {
        "$date": "2021-10-30T23:00:52.149Z"
      },
      "area": "c2acc5cc-9a7a-4406-8d91-79cb7f7ded70",
      "name": "car",
      "id": 492,
      "bearing": 327.2647737278924,
      "countingDirection": "rightleft_bottomtop",
      "angleWithCountingLine": 66.05160143993088
    },
    {
      "frameId": 175,
      "timestamp": {
        "$date": "2021-10-30T23:00:52.212Z"
      },
      "area": "56885eaf-9808-4b5e-b193-06b20e10c39d",
      "name": "car",
      "id": 469,
      "bearing": 281.30993247402023,
      "countingDirection": "rightleft_bottomtop",
      "angleWithCountingLine": 21.538940761379738
    }
  ]
}]

这是我残暴的管道,至少给了我我正在寻找的结果。所以我想,你如何优化这个?

[{$match: {
  _id:ObjectId('617dce992743dd52bed811a6')
}}, {$unwind: {
  path: "$counterHistory",
}}, {$group: {
  _id: "$counterHistory.id",
  maxDate:{$max:"$counterHistory.timestamp"},
  minDate:{$min:"$counterHistory.timestamp"}
}}, {$project: {
  _id:1,
  minDate:1,
  maxDate:1,
  noMatchingDates:{$ne:["$maxDate","$minDate"]}
}}, {$match: {
  noMatchingDates:true
}}, {$group: {
  _id: null,
  "avg_time": {
      "$avg": {
        "$subtract": [
          { "$ifNull": [ "$maxDate", 0 ] },
          { "$ifNull": [ "$minDate", 0 ] }
        ]
      }
  }
}}, {$project: {
  avg_time:1,
  hours: { $divide: [ "$avg_time", 3600000 ] },
  minutes: { $divide: [ "$avg_time", 60000 ] },
  seconds: { $divide: [ "$avg_time", 1000 ] }
}}]

【问题讨论】:

  • 给出一些测试数据,预期结果会更好
  • @YuTing 我刚刚添加了一条我拼凑起来的管道。真是太糟糕了,哈哈。
  • 是否只有一个匹配的 ObjectId 或者第一阶段可能有很多文档
  • 只有一个。
  • 想了想,只能说你的聚合看起来不错,一切都清晰高效。

标签: mongodb


【解决方案1】:

因此,正如我在上面提出并经 YuTing 确认的那样,这条管道有效:

[{$match: {
  _id:ObjectId('617dce992743dd52bed811a6')
}}, {$unwind: {
  path: "$counterHistory",
}}, {$group: {
  _id: "$counterHistory.id",
  maxDate:{$max:"$counterHistory.timestamp"},
  minDate:{$min:"$counterHistory.timestamp"}
}}, {$project: {
  _id:1,
  minDate:1,
  maxDate:1,
  noMatchingDates:{$ne:["$maxDate","$minDate"]}
}}, {$match: {
  noMatchingDates:true
}}, {$group: {
  _id: null,
  "avg_time": {
      "$avg": {
        "$subtract": [
          { "$ifNull": [ "$maxDate", 0 ] },
          { "$ifNull": [ "$minDate", 0 ] }
        ]
      }
  }
}}, {$project: {
  avg_time:1,
  hours: { $divide: [ "$avg_time", 3600000 ] },
  minutes: { $divide: [ "$avg_time", 60000 ] },
  seconds: { $divide: [ "$avg_time", 1000 ] }
}}]

【讨论】:

    猜你喜欢
    • 2019-02-22
    • 2021-09-03
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 2019-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多