1

I saved my data in MongoDb as

{
  "_id": "ObjectId(\"5fec31b6b9022035abbbf7cc\")",
  "message": {
    "date": "2020-12-30 13:20:26",
    "time": "2020-12-30T07:50:26.000Z",
    "ID": "005",
    "P": 1.36
  }
},
{
  "_id": "ObjectId(\"5fec31b5b9022035abbbf7c2\")",
  "message": {
    "date": "2020-12-30 13:20:24",
    "time": "2020-12-30T07:50:24.000Z",
    "ID": "005",
    "P": 1.5
  }
 
},
{
  "_id": "ObjectId(\"5fec31b0b9022035abbbf7b3\")",
  "message": {
    "date": "2020-12-30 13:20:19",
    "time": "2020-12-30T07:50:19.000Z",
    "ID": "005",
    "P": 1.63
  }
  
}

I want to find the average of P value per min. I've tried Group result by 15 minutes time interval in MongoDb but I got an error in the time field.

db.pressure.aggregate([
  { "$group": {
    "_id": {
      "year": { "$year": "message.time" },
      "dayOfYear": { "$dayOfYear": "message.time" },
      "hour": { "$hour": "message.time" },
      "interval": {
        "$subtract": [ 
          { "$minute": "message.time" },
          { "$mod": [{ "$minute": "message.time"}, 1] }
        ]
      }
    },
      
  
    "count": { "$sum": 1 }
  }
  }
  
])

{ "message" : "can't convert from BSON type string to Date", "ok" : 0, "code" : 16006, "codeName" : "Location16006", "name" : "MongoError" }

AkhilaV
  • 423
  • 3
  • 8
  • 18

1 Answers1

2

Few Fixes:

  • You need to convert your string date to date type using $toDate (From MongoDB 4.0), $addFields will update message.time field to date type
  • $year, $hour etc operators requires reference of field using $ sign you missed it in message.time
  • use $avg to get average of message.P
db.collection.aggregate([
  { $addFields: { "message.time": { $toDate: "$message.time" } } },
  {
    "$group": {
      "_id": {
        "year": { "$year": "$message.time" },
        "dayOfYear": { "$dayOfYear": "$message.time" },
        "hour": { "$hour": "$message.time" },
        "interval": {
          "$subtract": [
            { "$minute": "$message.time" },
            { "$mod": [{ "$minute": "$message.time" }, 15] }
          ]
        }
      },
      "count": { "$count": 1 },
      "average": { "$avg": "$message.P" }
    }
  }
])

Playground


MongoDB 3.6: you can use $dateFromString

  {
    $addFields: {
      "message.time": {
        $dateFromString: { dateString: "$message.time" }
      }
    }
  }

Playground

turivishal
  • 34,368
  • 7
  • 36
  • 59