How to add a computed field with expression-based value in Mongodb?

Asked

Viewed 128 times

-1

I’m trying to perform a query on Mongodb where I have the list of users, with a date column indicating the last time the user went online. In this query, based on the date and time the user went online I would like to add a new column $addFields with information whether the user is online, absent or offline.

My criteria would be something like this:

  • If the last time the user went online was 1 minute ago, then it’s online.
  • If the last time the user went online was 2 minutes ago, then he is away.
  • If the last time the user went online was 3 minutes ago, then it’s offline.

My data structure is as follows:

{
  _id: ObjectId('5ee191a8b3455000060c8296'),
  nome: 'Fulano'
  session_active: 2020-07-03T08:52:48.428+00:00
}

The result I was hoping for would be something like:

Server time: 08:52 am

{
  _id: ObjectId('5ee191a8b3455000060c8296'),
  nome: 'Fulano'
  session_active: 2020-07-03T08:52:00.428+00:00,
  status: 'Online'
}

Server time: 08:52 am

{
  _id: ObjectId('5ee191a8b3455000060c8296'),
  nome: 'Fulano'
  session_active: 2020-07-03T08:53:00.428+00:00,
  status: 'Ausente'
}

Server time: 08:52 am

{
  _id: ObjectId('5ee191a8b3455000060c8296'),
  nome: 'Fulano'
  session_active: 2020-07-03T08:54:00.428+00:00,
  status: 'Offline'
}

1 answer

0


What you want is to add one computed field, whose value will come from computing of existing values.

You can use a resource called Aggregation Pipeline to do this, which has some stages (called Stage by the documentation) in which some transformations are made in the documents at work.

You can use the $addFields Aggregation Stage to add a field derived from computing other existing values. It works like this:

db.collection.aggregate([
  {
    $addFields: {
      currentDate: new Date()
    }
  }
]);

With the above operation, Mongodb will return all data from collection with the countryside currentDate defined for the date on which the operation was carried out.

So you can use the operator $switch to define the computer field creation behavior status. Would something like this:

db.collection.aggregate([
  {
    $addFields: {
      // Adiciona o campo `status`:
      status: {
        $switch: {
          branches: [
            {
              case: {
                $gt: [
                  '$session_active',
                  // Data atual menos um minuto.
                  new Date(Date.now() - 1000 * 60 * 1)
                ]
              },
              then: 'Online'
            },
            {
              case: {
                $gt: [
                  '$session_active',
                  // Data atual menos dois minutos.
                  new Date(Date.now() - 1000 * 60 * 2)
                ]
              },
              then: 'Ausente'
            }
          ],
          default: 'Offline'
        }
      }
    }
  }
]);

After that, you can use the $match Aggregation Stage to carry out other possible filtrations.

Reference

  • Luiz Felipe, thank you so much for your contribution. She was of total help and solved the problem in which I was looking for the solution.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.