Presented below is a sample collection:
[
{ "_id" : ObjectId("5e7b38534512e95591e14c59"), "name" : "Luna", "online" : true },
{ "_id" : ObjectId("5e7b386b4512e95591e14c5a"), "name" : "Luna", "online" : false },
{ "_id" : ObjectId("5e7b386b4512e95591e14c5b"), "name" : "Luna", "online" : true },
{ "_id" : ObjectId("5e7b4e128e6bf5694924db09"), "name" : "Luna", "online" : false },
{ "_id" : ObjectId("5e7b4ec81b36e86a1fb754bf"), "name" : "Luna", "online" : true },
{ "_id" : ObjectId("5e7b4f3b1b36e86a1fb754c0"), "name" : "Luna", "online" : false },
{ "_id" : ObjectId("5e7b4f581b36e86a1fb754c1"), "name" : "Luna", "online" : true },
{ "_id" : ObjectId("5e7b5065f5700f6bee612040"), "name" : "Luna", "online" : false },
{ "_id" : ObjectId("5e7b51a3f5700f6bee612041"), "name" : "Luna", "online" : true },
{ "_id" : ObjectId("5e7b5885f5700f6bee612042"), "name" : "Luna", "online" : false },
{ "_id" : ObjectId("5e7b588ff5700f6bee612043"), "name" : "Luna", "online" : true }
]
The objective is to create a query that matches data between two specified dates and calculates the total online time during that period, using the MongoId for timestamp reference.
I have already figured out how to query data between these dates:
var objectIdFromDate = function (date) {
if(typeof date === 'string') date = new Date(date);
return ObjectId( Math.floor(date.getTime() / 1000).toString(16) + "0000000000000000" );
};
db.getCollection('timeline').aggregate([
{$match:{
name:"Luna",
_id:{
$gte: objectIdFromDate("2020-03-25T10:54:35.000Z"),
$lt: objectIdFromDate("2020-03-25T12:36:53.000Z")
}
}},
// ... ??? ...
])
The challenge lies in calculating the total online time by considering changes in online state (true=login, false=logout). The desired result document structure would be as follows:
{
name:"Luna",
totalTimeOnline:<datetime here>
}