Среднее временного интервала в монго - PullRequest
2 голосов
/ 20 апреля 2020

Я пытаюсь создать систему, в которой мне нужно составить в среднем данные за 2 минуты и отобразить их пользователю. Я пробовал групповые агрегатные функции. Но, возможно, я не правильно написал запрос.

 [
  {
    deviceid: 1,
    bucketSize: 4,
    first: 1573833152,
    last: 1573833155,
    samples: [
      {
        val: 10,
        time: 1573833152
      },
      {
        val: 15,
        time: 1573833153
      },
      {
        val: 14,
        time: 1573833154
      },
      {
        val: 16,
        time: 1573833165
      },
      {
        val: 22,
        time: 1573833166
      },
      {
        val: 26,
        time: 1573833167
      },
      {
        val: 27,
        time: 1573833168
      },
      {
        val: 28,
        time: 1573833169
      },
      {
        val: 29,
        time: 1573833170
      }
    ]
  },
  {
    deviceid: 1,
    bucketSize: 4,
    first: 1573833156,
    last: 1573833160,
    samples: [
      {
        val: 30,
        time: 1573833156
      },
      {
        val: 45,
        time: 1573833157
      },
      {
        val: 54,
        time: 1573833158
      },
      {
        val: 60,
        time: 1573833159
      },
      {
        val: 70,
        time: 1573833160
      }
    ]
  },
  {
    deviceid: 1,
    bucketSize: 4,
    first: 1573833161,
    last: 1573833165,
    samples: [
      {
        val: 10,
        time: 1573833161
      },
      {
        val: 15,
        time: 1573833162
      },
      {
        val: 14,
        time: 1573833163
      },
      {
        val: 20,
        time: 1573833164
      }
    ]
  }
]

Это данные. Мне нужно в среднем каждые 2 минуты. Я новичок в понедельник go. Следовательно застрял с этой проблемой. Большое спасибо заранее.

Детская площадка для среднего. Какой из членов stackoverflow помог мне создать. https://mongoplayground.net/p/tuTzNeO2DKx

1 Ответ

1 голос
/ 20 апреля 2020

Для меня не совсем понятно, что вы подразумеваете под «мне нужно в среднем каждые 2 минуты». Все ваши образцы данных попадают в один 2-минутный интервал.

В любом случае, ключевой операцией является определение 2-минутного интервала. После этого вы можете $group на samples.interval значение. Вы можете сделать это следующим образом:

db.collection.aggregate([
   { $unwind: "$samples" },
   {
      // convert time value into proper 'Date' object and split into parts
      $addFields: {
         "samples.interval": {
            $dateToParts: {
               date: {
                  $toDate: {
                     $multiply: [1000, "$samples.time"]
                  }
               }
            }
         }
      }
   },
   {
      // Build new 2-Minute interval. `samples.interval` represents the start time of 2-Minute interval
      $addFields: {
         "samples.interval": {
            $dateFromParts: {
               year: "$samples.interval.year",
               month: "$samples.interval.month",
               day: "$samples.interval.day",
               hour: "$samples.interval.hour",
               minute: { $subtract: ["$samples.interval.minute", { $mod: ["$samples.interval.minute", 2] }] }
            }
         }
      }
   },
   {
      $group: {
         _id: {
            deviceid: "$deviceid",
            interval: "$samples.interval"
         },
         average: { $avg: "$samples.val" }
      }
   },
   { $replaceRoot: { newRoot: { $mergeObjects: ["$$ROOT", "$_id"] } } },
   { $unset: "_id" }
])

Вы можете использовать

minute: { $add: [1, { $subtract: ["$samples.interval.minute", { $mod: ["$samples.interval.minute", 2] }] }] }

, чтобы получить интервал как interval: ISODate("2019-11-15T17:27:00.000+0100") ± 1 Minute, а не как "начало интервала"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...