You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js操作MongoDB:生成起止时间间隔序列遇阻

Solution for Generating Time Intervals from MongoDB Schedule Document

Hey there! I see you're trying to generate a series of time points between start and end in your Schedule collection, incrementing by a specified duration. The issue with your current approach is that $add only performs a single addition—so you're just getting the first incremented time instead of the full sequence. Let's fix this with two solid approaches: one using MongoDB's aggregation pipeline, and another handling the logic on the Node.js side.

Option 1: MongoDB Aggregation Pipeline (Server-Side)

We can use MongoDB's aggregation operators like $range, $map, $subtract, and $multiply to generate the full sequence directly in the database. Here's how it works:

  1. Match the target Schedule document using its _id.
  2. Calculate the total number of intervals by dividing the time difference between end and start by your duration (plus 1 to include the end time).
  3. Use $range to create an array of integers representing each interval index.
  4. Map each index to a time point by adding the index multiplied by the duration to the start time, and assign an incrementing id.
  5. Unwind the array of intervals and replace the root to get each interval as a separate document.

Here's the updated code:

const { idSchedule } = req.params;
const { duration } = req.body;
const durationMs = duration * 60 * 1000;
const objId = new ObjectID(idSchedule);

Schedule.aggregate([
  { "$match": { "_id": objId } },
  {
    "$project": {
      "_id": 0,
      "intervals": {
        "$map": {
          "input": {
            "$range": [
              0,
              { "$add": [
                { "$divide": [ { "$subtract": [ "$end", "$start" ] }, durationMs ] },
                1
              ] }
            ]
          },
          "as": "i",
          "in": {
            "id": { "$add": [ "$$i", 1 ] },
            "time": { "$add": [ "$start", { "$multiply": [ "$$i", durationMs ] } ] }
          }
        }
      }
    }
  },
  { "$unwind": "$intervals" },
  { "$replaceRoot": { "newRoot": "$intervals" } }
]).then((response) => { res.send(response) })
.catch(err => res.status(500).send(err));

Option 2: Node.js Side Processing (Client-Side)

If you prefer more straightforward logic or are working with an older MongoDB version that doesn't support some aggregation operators, you can fetch the document first and generate the intervals in your Node.js code:

const { idSchedule } = req.params;
const { duration } = req.body;
const durationMs = duration * 60 * 1000;
const objId = new ObjectID(idSchedule);

Schedule.findById(objId)
  .then(doc => {
    const intervals = [];
    let currentTime = new Date(doc.start);
    const endTime = new Date(doc.end);
    let id = 1;

    // Loop until we pass the end time
    while (currentTime <= endTime) {
      intervals.push({
        id: id++,
        time: currentTime.toISOString()
      });
      // Increment the current time by the duration
      currentTime = new Date(currentTime.getTime() + durationMs);
    }

    res.send(intervals);
  })
  .catch(err => res.status(500).send(err));

Key Notes:

  • Both approaches ensure you include the end time as the final interval (as long as the duration divides evenly into the total time difference, or even if it doesn't—though you might want to adjust logic if partial intervals aren't desired).
  • Make sure your start and end fields are stored as MongoDB Date types (not strings) for accurate date arithmetic. If they're strings, you'll need to convert them using $toDate in the aggregation pipeline, or new Date() in Node.js.

内容的提问来源于stack exchange,提问作者zyka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 23:42:36