Trabajar con Fechas en MongoDB

MongoDBBeginner
Practicar Ahora

Introducción

En este laboratorio, aprenderá a trabajar con fechas en MongoDB. Practicará la inserción de documentos con valores de fecha, la consulta de documentos dentro de rangos de fechas específicos, el formato de campos de fecha para su visualización, la actualización de campos de fecha existentes y la ordenación de colecciones por fecha. Este laboratorio proporciona una guía completa y práctica de las funcionalidades relacionadas con las fechas de MongoDB, que son esenciales para la gestión de datos de series temporales, la programación y las aplicaciones de registro.

Insertar Documentos con Valores de Fecha

En este primer paso, se conectará al servidor de MongoDB e insertará varios documentos que contienen valores de fecha. Esto sentará las bases para las consultas y operaciones que realizará en los pasos posteriores.

Primero, abra la shell de MongoDB ejecutando el comando mongosh en su terminal. Esto lo conectará a la instancia de MongoDB en ejecución.

mongosh

Una vez dentro de la shell, verá un prompt como test>. Cambiemos a una nueva base de datos llamada datelab. Si la base de datos no existe, MongoDB la creará por usted cuando inserte datos por primera vez.

use datelab

Ahora, insertará tres documentos en una nueva colección llamada events. Cada documento representará un evento e incluirá una fecha. MongoDB almacena las fechas como objetos BSON Date, que puede crear utilizando el constructor new Date().

Inserte los siguientes documentos uno por uno. El primero utiliza una cadena de fecha ISO-8601, el segundo utiliza la fecha y hora actuales, y el tercero utiliza una marca de tiempo Unix en milisegundos.

db.events.insertOne({
    event_name: "Conference",
    date: new Date("2024-06-15T10:30:00Z")
})
db.events.insertOne({
    event_name: "System Maintenance",
    timestamp: new Date()
})
db.events.insertOne({
    event_name: "Project Deadline",
    timestamp: new Date(1718476800000)
})

Después de insertar los documentos, puede verificar que se agregaron correctamente utilizando el método find(), que recupera todos los documentos de la colección.

db.events.find()

Su salida debería ser similar a esta, aunque los valores de _id y el timestamp para "System Maintenance" serán diferentes para usted.

[
  {
    _id: ObjectId("65d38f8a1c2d3e4f5a6b7c8d"),
    event_name: 'Conference',
    date: ISODate('2024-06-15T10:30:00.000Z')
  },
  {
    _id: ObjectId("65d38f9c1c2d3e4f5a6b7c8e"),
    event_name: 'System Maintenance',
    timestamp: ISODate('2024-02-19T14:55:24.123Z')
  },
  {
    _id: ObjectId("65d38fb11c2d3e4f5a6b7c8f"),
    event_name: 'Project Deadline',
    timestamp: ISODate('2024-06-15T18:00:00.000Z')
  }
]

Ahora ha insertado correctamente documentos con valores de fecha. En el siguiente paso, aprenderá a consultar estos documentos basándose en sus fechas.

Consultar Documentos por Rango de Fechas

Con los datos en su colección, ahora puede realizar consultas para encontrar documentos que caigan dentro de rangos de fechas específicos. Este es un requisito común para aplicaciones que manejan eventos programados, registros o datos sensibles al tiempo.

Primero, agreguemos más eventos a nuestra colección para hacer las consultas más interesantes. Usaremos el método insertMany() para agregar tres documentos a la vez.

db.events.insertMany([
    {
        event_name: "Summer Conference",
        date: new Date("2024-07-15T09:00:00Z")
    },
    {
        event_name: "Winter Workshop",
        date: new Date("2024-01-20T14:30:00Z")
    },
    {
        event_name: "Spring Meetup",
        date: new Date("2024-04-10T11:15:00Z")
    }
])

Ahora tiene un total de seis eventos. Busquemos todos los eventos que ocurrieron después del 1 de junio de 2024. Para hacer esto, usará el operador "mayor que", $gt.

db.events.find({
    date: { $gt: new Date("2024-06-01") }
})

A continuación, busquemos todos los eventos que ocurrieron en la primera mitad de 2024, específicamente entre el 1 de enero y el 1 de junio. Puede combinar los operadores "mayor o igual que" ($gte) y "menor que" ($lt) para esto.

db.events.find({
    date: {
        $gte: new Date("2024-01-01"),
        $lt: new Date("2024-06-01")
    }
})

La consulta devolverá los eventos "Winter Workshop" y "Spring Meetup". La salida debería ser similar a esta:

[
  {
    _id: ObjectId("65d392a11c2d3e4f5a6b7c91"),
    event_name: 'Winter Workshop',
    date: ISODate('2024-01-20T14:30:00.000Z')
  },
  {
    _id: ObjectId("65d392a11c2d3e4f5a6b7c92"),
    event_name: 'Spring Meetup',
    date: ISODate('2024-04-10T11:15:00.000Z')
  }
]

Estos ejemplos demuestran cómo usar operadores de comparación ($gt, $gte, $lt, $lte) para filtrar eficazmente documentos basándose en campos de fecha.

Formatear Salida de Fecha con Agregación

A menudo, necesita mostrar fechas en un formato específico y legible por humanos. El framework de agregación de MongoDB proporciona herramientas potentes para esto. En este paso, utilizará el operador $dateToString para formatear sus campos de fecha.

El framework de agregación procesa documentos a través de una canalización (pipeline) de etapas. Utilizaremos una etapa $project para remodelar nuestros documentos y crear un nuevo campo de fecha formateado.

Vamos a formatear el campo date de nuestros eventos en un formato AAAA-MM-DD. Esta consulta procesará solo los documentos que tengan un campo date.

db.events.aggregate([
    {
        $project: {
            event_name: 1,
            formatted_date: {
                $dateToString: {
                    format: "%Y-%m-%d",
                    date: "$date"
                }
            }
        }
    }
])

Analicemos este comando:

  • db.events.aggregate([...]): Inicia una canalización de agregación en la colección events.
  • $project: Una etapa que remodela los documentos. Incluimos event_name y creamos un nuevo campo formatted_date.
  • $dateToString: Un operador que convierte un objeto de fecha en una cadena.
  • format: "%Y-%m-%d": Especifica el formato de salida. %Y es el año, %m es el mes y %d es el día.
  • date: "$date": Especifica el campo de fecha de entrada del documento original. El prefijo $ indica una ruta de campo.

La salida mostrará el nombre del evento original y la nueva cadena de fecha formateada. Tenga en cuenta que los documentos sin un campo date (como "System Maintenance") se omitirán del resultado.

[
  { _id: ObjectId("..."), event_name: 'Conference', formatted_date: '2024-06-15' },
  { _id: ObjectId("..."), event_name: 'Summer Conference', formatted_date: '2024-07-15' },
  { _id: ObjectId("..."), event_name: 'Winter Workshop', formatted_date: '2024-01-20' },
  { _id: ObjectId("..."), event_name: 'Spring Meetup', formatted_date: '2024-04-10' }
]

También puede extraer componentes individuales de una fecha, como el año o el mes, utilizando operadores como $year y $month.

db.events.aggregate([
    {
        $project: {
            event_name: 1,
            year: { $year: "$date" },
            month: { $month: "$date" },
            day: { $dayOfMonth: "$date" }
        }
    }
])

Esto le brinda un control detallado sobre cómo procesa y presenta la información de las fechas.

Actualizar Campos de Fecha

Sus datos no son siempre estáticos. Es posible que necesite actualizar campos de fecha, como reprogramar un evento o agregar una marca de tiempo de modificación. En este paso, aprenderá cómo actualizar campos de fecha utilizando varios operadores de actualización.

Primero, reprogramemos el evento "Conference" a una nueva fecha. Usaremos el método updateOne() para apuntar a un solo documento y el operador $set para cambiar su campo date.

db.events.updateOne(
    { event_name: "Conference" },
    {
        $set: {
            date: new Date("2024-09-01T10:00:00Z"),
            status: "Rescheduled"
        }
    }
)

Ahora, realicemos una actualización masiva. Marcaremos todos los eventos que ocurrieron antes del 1 de mayo de 2024 como "Archived". También agregaremos un nuevo campo, last_modified, para registrar cuándo ocurrió esta actualización. El método updateMany() modificará todos los documentos coincidentes, y el operador $currentDate es perfecto para establecer un campo con la hora actual del servidor.

db.events.updateMany(
    { date: { $lt: new Date("2024-05-01") } },
    {
        $set: { status: "Archived" },
        $currentDate: { last_modified: true }
    }
)

Verifiquemos los cambios recuperando todos los documentos. El método .pretty() está obsoleto, por lo que simplemente usaremos find().

db.events.find()

Verá que la "Conference" tiene una nueva fecha y estado. El "Winter Workshop" y el "Spring Meetup" ahora están marcados como "Archived" y tienen una marca de tiempo last_modified.

Ejemplo de salida para un evento archivado:

{
 "_id" : ObjectId("..."),
 "event_name" : "Winter Workshop",
 "date" : ISODate("2024-01-20T14:30:00Z"),
 "status" : "Archived",
 "last_modified" : ISODate("2024-02-19T15:10:00Z")
}

Estas operaciones muestran cómo puede modificar con precisión la información relacionada con las fechas en sus documentos.

Ordenar Documentos por Fecha

La última operación fundamental que aprenderá es la ordenación. Mostrar eventos en orden cronológico es un requisito común. MongoDB facilita la ordenación de los resultados de su consulta por cualquier campo, incluidas las fechas.

Para ordenar documentos, agregue el método .sort() a una consulta find(). El método sort() toma un documento que especifica el campo por el cual ordenar y el orden de ordenación. Un valor de 1 indica orden ascendente (del más temprano al más tardío), y -1 indica orden descendente (del más tardío al más temprano).

Recuperemos todos los eventos ordenados por su date en orden ascendente.

db.events.find().sort({ date: 1 })

Esto listará los eventos desde el "Winter Workshop" (el más temprano) hasta el "Summer Conference" (el más tardío). Los documentos sin un campo date se ordenarán primero si se incluyen en la consulta.

Ahora, ordenemos los eventos en orden descendente para ver primero los eventos más recientes.

db.events.find().sort({ date: -1 })

También puede combinar la ordenación con el filtrado. Por ejemplo, busquemos todos los eventos que no están archivados y ordenémoslos por fecha.

db.events.find({ status: { $ne: "Archived" } }).sort({ date: 1 })

La salida mostrará los eventos no archivados en orden cronológico.

[
  {
    _id: ObjectId("..."),
    event_name: 'System Maintenance',
    timestamp: ISODate("...")
  },
  {
    _id: ObjectId("..."),
    event_name: 'Project Deadline',
    timestamp: ISODate('2024-06-15T18:00:00.000Z')
  },
  {
    _id: ObjectId("..."),
    event_name: 'Summer Conference',
    date: ISODate('2024-07-15T09:00:00.000Z')
  },
  {
    _id: ObjectId("..."),
    event_name: 'Conference',
    date: ISODate('2024-09-01T10:00:00.000Z'),
    status: 'Rescheduled'
  }
]

La ordenación es una herramienta crucial para presentar datos ordenados por tiempo de manera significativa. Cuando haya terminado, puede salir del shell de MongoDB escribiendo exit o presionando Ctrl+D.

Resumen

En este laboratorio, ha aprendido las técnicas fundamentales para trabajar con fechas en MongoDB. Comenzó insertando documentos con valores de fecha utilizando diferentes formatos. Luego practicó la consulta de documentos basada en rangos de fechas con operadores de comparación. Después de eso, exploró el framework de agregación para formatear campos de fecha para una mejor legibilidad. También aprendió a actualizar campos de fecha y agregar marcas de tiempo de modificación. Finalmente, dominó la ordenación de colecciones por fecha para presentar datos en orden cronológico. Estas habilidades son esenciales para cualquier desarrollador que trabaje con datos basados en tiempo en MongoDB.