Banco de Dados

7 fev, 2012

Trabalhando com datas no MongoDB

Publicidade

Olá, pessoal! Neste artigo vou abordar um tópico que gera muito confusão com desenvolvedores e profissionais de tecnologia que estão começando a adotar o MongoDB como banco de dados NoSQL: como trabalhar com datas.

Para começar, é importante salientar que o MongoDB é um banco de dados que possui a característica de ser schema free, ou seja, o que podemos armazenar nele não precisa seguir um formato certinho, como se fossem linhas e colunas de uma tabela em um banco de dados relacional. A propósito, o MongoDB utiliza termos diferentes, como documento, coleção e atributo, ao invés dos tradicionais: tabela, linha e coluna. Para quem procura mais informações básicas, recomendo este artigo sobre MongoDB  publicado aqui no iMasters.

Toda a estrutura de armazenamento do MongoDB segue a especificação BSON e, por isso, o valor das datas é armazenado internamente como um inteiro de 64 bits (com valores positivos e negativos) que contém a quantidade de milisegundos desde primeiro de janeiro de 1970. Valores positivos indicam datas depois deste marco inicial e valores negativos indicam datas anteriores a ele. Porém, na prática, trabalhamos com a função Date() ou ISODate() de  maneira semelhante à manipulações de datas no JavaScript. Por exemplo: para criar uma coleção ColDate no banco de dados dbExemplo, com o atributo aDate contendo um documento com a data atual, precisamos da seguinte sequência de comandos no shell do MongoDB:

> use dbExemplo;
> db.ColDate.insert({ meu_id: 1, aDate: new Date() });

Para verificar o conteúdo desta coleção, podemos utilizar o método find() desta maneira:

> db.ColDate.find();

Que retornará o documento similar a:

{ "_id" : ObjectId("..."), "meu_id": 1, "aDate": ISODate("2012-01-27T12:47:51.5207") }

Para trabalhar com a função ISODate() devemos especificar a data no formato “YYYY-MM-DD hh:mm:ss”, dentre outros possíveis. Por exemplo: a inserção de um documento com a data de 1º de maio de 2012 às 12h30 ficaria:

> db.ColDate.insert({ aDate: new ISODate('2012-05-01 12:30:00') });

Notem que a conversão para o formato de data necessário fica a cargo do cliente que conectar e acessar as informações armazenadas no MongoDB. Para obter partes da data, podemos utilizar os seguintes métodos do tipo de dados Date:

// Obtém um documento JSON a partir da coleção criada:
> var doc = db.ColDate.findOne({meu_id: 1});
// Obtém o dia do mês com o método getDate()
> doc.aDate.getDate();
// Obtém o mês com o método getMonth(). Nota: Janeiro = 0 e Dezembro = 11
> doc.aDate.getMonth();
// Obtém a ano com o método getFullYear()
> doc.aDate.getFullYear();

Para quem prefere obter os dados do MongoDB e trabalhar com eles diretamente no JavaScript visando formatação recomendo este link, que contém uma descrição de como realizar tais manipulações. O mesmo vale para operações mais complexas como soma, subtração e descoberta de períodos entre datas: recomenda-se utilizar tais operações diretamente na linguagem que acessa o MongoDB. Já para comparações, podemos utilizar os operadores descritos abaixo:

$gt       => GREATER THEN (maior que). Símbolo tradicional: >
$gte     => GREATER THEN OR EQUAL (maior ou igual). Símbolo tradicional: >=
$lt        => LESS THEN (menor). Símbolo tradicional:  <
$lte      => LESS THEN OR EQUAL (menor ou igual). Símbolo tradicional: <=
$ne      => NOT EQUAL (diferente). Símbolos tradicionais: != ou <>

Veremos alguns exemplos destes operadores lembrando que o operador de igualdade é feito diretamente no filtro do documento, como no caso do método findOne(), utilizado em um exemplo anterior.

// Todas as datas além de primeiro de janeiro de 2012
> db.ColDate.find({ aDate: { $gt: ISODate('2012-01-01') } });
// Todas as datas depois de 27 de janeiro de 2012 inclusive
> db.ColDate.find({ aDate: { $gte: ISODate('2012-01-27') } });
// Todas as datas antes de 1 maio de 2012
> db.ColDate.find({ aDate: { $lt: ISODate('2012-05-01') } });
// Todas as datas antes de 1 maio de 2012 inclusive
> db.ColDate.find({ aDate: { $lte: ISODate('2012-05-01') } });
// Todas as datas diferentes de 1 maio de 2012
> db.ColDate.find({ aDate: { $ne: ISODate('2012-05-01') } });

Com isso terminamos este artigo curto e simples sobre como trabalhar com datas no MongoDB. Espero ter ajudado aqueles que estão começando a dar os primeiros passos neste banco de dados NoSQL e ainda tem dúvidas sobre como trabalhar com datas.

Um grande abraço e até o próximo artigo!