Atualizando a lista de Timezone da JVM

Olá pessoal vamos falar sobre como atualizar a lista de Timezone da JVM.

O Problema da Mudança de Timezone


Devido uma mudança realizada pelo governo brasileiro, este ano não teremos o horário de verão, que mudava o GMT para -2 em algumas regiões do Pais, com isso, as configurações de Timezone dos servidores são ajustados para não realizar a mudança, mas alguns ambientes onde temos JVM podem acabar mudando e não seguindo o Timezone do S.O, pois a regra antiga ainda encontra-se configurada.

Ambiente Java 10 mudou com Timezone incorreto.

Acima instanciamos um objeto Date() a partir do JShell e notamos a diferença no horário, onde o correto seria exibir 11:05:31.


Lista de Timezone Atualizados


Como aconteceu aqui no Brasil, podem acontecer mudanças de Timezone em qualquer lugar (mesmo não sendo comum), quando ocorrem essas mudanças temos que recorrer a listas de Timezone atualizadas para que os ambientes possam funcionar corretamente.

No caso da JVM, a Oracle mantém a lista de Timezone baseada na IANA.

Para corrigir o nosso problema iremos utilizar a seguinte URL: https://www.iana.org/time-zones/repository/tzdata-latest.tar.gz, esta irá retornar a ultima lista atualizada de Timezones.

A Ferramenta TZUpdater


A Oracle disponibiliza uma ferramenta para atualizar a lista de Timezone chamada TZUpdater, esta é um arquivo jar que deve ser executado passando a lista de atualização como parâmetro.


Realizando a execução


Para executar o utilitário devemos executar o seguinte comando:

java -jar tzupdater.jar  -l https://www.iana.org/time-zones/repository/tzdata-latest.tar.gz


Se tudo ocorrer corretamente o resultado será o seguinte:


Descritivo da execução do comando.

Obs: Vale lembrar que caso você tenha mais de uma JVM no ambiente, ao executar o comando java, a lista que será atualizada é a que for sua JAVA_HOME e estiver configurada em seu PATH, caso sua necessidade seja alterar de outras JVM, use o caminho absoluto, por exemplo: /opt/path_java/bin/java


Após a atualização vamos criar novamente um objeto Date:


Ambiente Java 10 com o Timezone correto.

Após a execução do tzupdater a lista foi alterada e o Timezone esta de acordo com as configurações Locais.

Referências


Skipping Tests, Profiles e Debug com Maven

Olá pessoal, hoje iremos ver alguns comandos utilitários no processo de build do Maven.

O Processo de Build

O Maven é uma ferramenta que trás muitos benefícios ao ambiente de desenvolvimento, com ele gerenciamos dependências, versionamento e configurações dos projetos.

Uma parte muito importante que devemos nos atentar é com o processo de build, este processo é composto pela execução de todo o ciclo de vida do Maven, execução dos plugins presentes no pom.xml e a criação do artefato final.

É comum nos depararmos com builds que demoram vários minutos para completar, caso seja o seu caso, existem algumas métricas que dizem que "um processo de build não deve demorar mais que 5 minutos".

Maven Skip Tests

A execução dos testes é algo fundamental em projetos de softwares, mas as vezes nos deparamos com cenários onde precisamos executar o processo de build e não executar o pipeline de testes, com Maven temos 3 maneiras de executar tal tarefa, sendo:


Plugin


<plugin>        
 <groupId>org.apache.maven.plugins</groupId>
 <artifactId>maven-surefire-plugin</artifactId>
 <version>2.12.4</version>
 <configuration>
    <skipTests>true</skipTests>
 </configuration>
</plugin>

Linha de Comando


mvn install -DskipTests

Linha de Comando, evitando a compilação dos Testes


mvn install -Dmaven.test.skip=true

Maven Profiles

Profiles é algo que praticamente todos ambientes de desenvolvimento necessitam, isso porque é comum termos particularidade entre os ambientes de desenvolvimento, testes, homologação e produção.

No Maven temos os profiles de build, estes permitem que de acordo com o profile configurado, diferentes processos e plugins sejam executados, para executarmos profile devemos fazer o seguinte:

<profiles>
   <profile>
      <id>dev</id>
       <!-- Código do build -->
   </profile>
   <profile>
      <id>homolog</id>
      <!-- Código do build -->
   </profile>
   <profile>
      <id>prod</id>
      <!-- Código do build -->
   </profile>
<profiles>

Após termos a configuração no pom.xml, podemos executar informando qual profile queremos executar:

mvn package -P dev

Aqui podemos ver a flag -P esta determina qual profile queremos que nosso build execute.

Maven Debug

Uma coisa muito comum é realizar o debug de um processo de build, esta operação nos permite verificar cada execução do processo, analisando qual o fluxo de cada parte do build.

No Maven, o padrão é executar todo o processo como INFO, ou seja, apesar informações essenciais serão exibidas no console, para executar o build em modo debug podemos passar a flag -X, como o abaixo:

mvn package -X

Todas essas pequenas configurações que realizamos ajudam no processo de build, tornando mais simples encontrar bugs, executar diferentes processos e encontrar problemas de performance.

Até a próxima.

Referências


Analisando na Prática o uso de Primitivos e Wrappers

O uso de tipos primitivos e Wrappers é um tema que traz diversas discussões, inclusive existem vários tutorias que mostram a aplicabilidade de cada uma das estratégias em diferentes cenários.

As Classes Wrappers


As classes Wrappers são aquelas que representam os tipos primitivos da linguagem Java, há algum tempo existiam autores que falavam que Java não era uma linguagem 100% OO por tratar os tipos básicos como primitivos, mas isso acabou quando adicionaram os tipos Wrappers a linguagem.

O Wrappers são classes imutáveis, e possuem vários métodos utilitários que facilitam conversões, parses, formatação, entre outras funcionalidades bem utilizadas no dia a dia.

Vamos analisar cada tipo primitivo e sua representação em classe Wrapper:
  • byte
    • Byte;
  • short
    • Short;
  • int
    • Integer;
  • long
    • Long;
  • boolean
    • Boolean;
  • char
    • Character;
  • float
    • Float;
  • double
    • Double;

Comparação entre Wrappers


Vamos entender como esses objetos funcionam no quesito comparação, já analisei casos onde uma comparação de valores iguais não resultavam em true, vamos analisar alguns motivos para isso ocorrer:

 Integer oneWrapper = 1; //Autoboxing do valor <1> para a variavel oneWrapper
 Integer twoWrapper = 1; //Autoboxing do valor <1> para a variavel twoWrapper
  
 System.out.println(" Comparação de Wrappers \n");
 System.out.println(oneWrapper == twoWrapper);
 System.out.println(oneWrapper != twoWrapper);
 System.out.println(oneWrapper.equals(twoWrapper));

O Resultado do nosso código será o seguinte:
oneWrapper == twoWrapper : true
oneWrapper != twoWrapper : false
oneWrapper.equals(twoWrapper) : true

Para entender os resultado, vamos lembrar que quando criamos as variáveis do tipo Wrapper realizando a atribuição direta de um valor, o compilador realiza o autoboxing, que é a conversão de um tipo primitivo em tipo Wrapper.

Na primeira condição temos oneWrapper == twoWrapper, quando comparamos objetos com == a comparação acontece entre as referências dos objetos, e neste caso como as variáveis foram criadas através de atribuição direta, o valor 1 será reaproveitado do pool de objetos, assim as variáveis apontaram para o mesmo objeto em memória.

Na segunda condição temos oneWrapper != twoWrapper, aqui a explicação é a mesma da primeira.

Na terceira condição temos oneWrapper.equals(twoWrapper), quando aprendemos manipulação de objetos com Java, analisamos o método equals(), que é o método que utilizamos para analisar se um objeto é igual ao outrolembrando que os Wrappers são objetos, portanto o equals é a melhor forma de realizar a comparação.


Integer oneWrapper = 1; //Autoboxing do valor <1> para a variavel oneWrapper
Integer twoWrapper = new Integer(1); //Criação sem reaproveitar o objeto do pool
  
System.out.println(" Comparação de Wrappers com Instância direta \n");
System.out.println(oneWrapper == twoWrapper);
System.out.println(oneWrapper != twoWrapper);
System.out.println(oneWrapper.equals(twoWrapper));

O resultado será o seguinte:

oneWrapper == twoWrapper        : false
oneWrapper != twoWrapper         : true
oneWrapper.equals(twoWrapper) : true

Vamos entender o resultado, no primeiro exemplo é feita uma comparação entre 2 Wrappers utilizando o operador ==, mas os objetos foram criados de forma diferente, na variável oneWrapper foi realizado a atribuição do valor diretamente onde irá ser realizado o autoboxing, já a variável twoWrapper foi criada utilizando o construtor de Integer.

Ao criar utilizando o construtor, não reaproveitamos objetos do pool de objetos, ou seja, foi criado outro objeto em memória, e como já sabemos o operador == realiza a comparação entre referências, portanto resultado da comparação é false.

No segundo exemplo utilizando o operador != aqui o conceito é o mesmo do exemplo anterior, o valor de ambas as variáveis é 1, mas lembrando que o operador irá comparar referências que são diferentes portanto o resultado é true.

Já no terceiro exemplo utilizamos o método equals() para realizar a comparação, neste caso o que será avaliado é o valor das variáveis, portanto o resultado é true.

Analisando a Performance


Um ponto importante é analisarmos a performance das operações de boxing dentro de estruturas de repetição, estas operações são custosas pois exigem  muitas transformação em laços.

Vamos analisar alguns códigos para entendermos os casos.

long init = System.currentTimeMillis();
  
long result = 0;
  
for (long i = 0; i < 1000000000; i++) {
     result += i;
}
  
long end = System.currentTimeMillis();
  
System.out.println(" Tempo: "+(end - init)); 

O Resultado da execução é:  Tempo: 460

Esse é um código onde apenas executamos um soma entre as variáveis result e i utilizando o operador += , perceba que como estamos usando o tipo long a soma acontece sem maiores problemas.


long init = System.currentTimeMillis();
  
Long result = 0L;
  
for (long i = 0; i < 1000000000; i++) {
     result += i;
}
  
long end = System.currentTimeMillis();
  
System.out.println(" Tempo: "+(end - init));

O Resultado da execução é:  Tempo: 5043

Este exemplo é quase igual ao anterior, a unica diferença que a variável result agora é do tipo Wrapper Long e não long primitiva, após a execução notamos um tempo superior ao do primeiro exemplo.

Acontece que o operador += só pode ser usado em operações de tipos primitivos, e em nosso exemplo a variável result é uma Wrapper, e neste caso a JVM é obrigada a realizar a operação de Autoboxing, deixando o laço mais lento.

Conclusão


O uso de Wrapper e Primitivos deve ser analisado em cada cenário, levando em consideração as operações que serão executadas, performance, cálculos, entre outros fatores.

Os recursos de Autoboxing e Unboxing são muito bons e deixaram a criação e manipulação de objetos mais produtiva, mas sempre devemos nos atentar para não utilizar em lugares onde poderemos ter problemas de performance.

Até mais.

Código Fonte

Referências


Ferramentas Gráficas para MongoDB

Olá pessoal, hoje iremos analisar algumas ferramentas gráficas para utilização do banco de dados MongoDB.

As Ferramentas

Em banco de dados relacionais é comum interagirmos com os databases por meio de alguma ferramenta gráfica, por exemplo, com PostgreSQL podemos usar o pgadmin, com Oracle temos o SQL Developer, entre outras.

Com MongoDB, além do tradicional console, temos várias opções no mercado, sendo elas open source ou pagas, vou listar 2 que venho utilizando:
  • Robo3T (conhecido como Robomongo);
  • NoSQLBooster for MongoDB.


Robo3T

Esta foi a primeira ferramenta na qual tive contato ao entrar no mundo do MongoDB, anteriormente era conhecida como RoboMongo, ela possui uma interface simples e de fácil utilização e está disponível para Linux. Mac e Windows.


Interface inicial do Robo3T.

Uma das grandes vantagens que vejo nesta ferramenta é a facilidade de realizar consulta e visualizar os dados, para isso basta clicar sobre uma coleção e a consulta já será realizada fornecendo diferentes opções de visualização, sendo em tree, table ou json. 

Visualização de dados de uma coleção.

Esta é uma ferramenta que venho utilizo bastante, e que também possui uma boa aceitação pelo comunidade de desenvolvimento.

NoSQLBooster for MongoDB

Esta ferramenta é mais robusta e com vários recursos, sua interface lembra uma IDE, onde temos vários recursos interessantes mesmo utilizando a versão free, esta disponível para Linux, Mac e Windows.



Interface inicial do NoSQL Booster for MongoDB.

Até o momento possui uma edição free para uso pessoal/comercial mas com funções limitadas, para detalhes sobre licença e termos de uso, consulte o site oficial da ferramenta.

Detalhes sobre versão e descrição de licença.

No site existe listas de comparação de features disponíveis em cada versão, vale a pena analisar e definir qual versão se adapta melhor a sua necessidade:


A visualização dos dados é bem detalhada, possuindo recursos bem interessantes como exportação, manipulação de dados direto no grid, entre outras. 

Visualização de dados de uma coleção.

A ferramenta possui um recurso bem interessante, ao clicar sobre uma coleção ou index será exibido informações administrativas, como tamanho em disco, engine, etc, isso ajuda bastante quando temos que analisar recursos utilizados pelo database.

Visualizando detalhes da coleção.

Conclusão

Existem várias outras ferramentas disponíveis no mercado, listei as 2 que tenho experiência, e atualmente tenho utilizado, acredito que vale a pena realizar testes e ter ambas em seu ambiente, dessa forma será aproveitado o melhor de cada uma delas.


Referências



Utilizando LocalDate, LocalDateTime e LocalTime na Prática

Tudo bem pessoal, hoje iremos avaliar e analisar operações de manipulação de Datas envolvendo a JavaTime API introduzida no Java 8.

Exemplos da java.time API


Já se passaram alguns anos desde o lançamento do Java 8 e mesmo após este período, há empresas que desconhecem o poder da java.time API, esta foi uma nova API de datas introduzida no Java 8 visando resolver problemas que tínhamos com as velhas classes Date e Calendar.

Vamos mostrar vários exemplos práticos do uso da API:

Criação de objetos

No exemplo abaixo, estamos criando os objetos para manipulação de datas, perceba que temos 3 tipos, sendo LocalDate para manipular datas, LocalDateTime para manipular data/hora e LocalTime para horas:

LocalDate localDate      = LocalDate.now();
LocalDateTime localDateTime = LocalDateTime.now();
LocalTime localTime      = LocalTime.now();

Utilizando formatação

Aqui realizamos a operação de formatação, perceba que não foi necessário utilizar a classe SimpleDateFormat, que usaríamos em conjunto com Date ou Calendar, aqui utilizamos a DateTimeFormatter passando o formato desejado:

String strLocalDate2   = LocalDateTime.now().format(DateTimeFormatter.ofPattern("dd/MM/yyyy"));
String strLocalDateTime2 = LocalDateTime.now().format(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"));
String strLocalTime2   = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"));

Adicionando dias, meses e horas

Um recurso muito interessante são os métodos de adicionar períodos, quem já trabalhou com Calendar sabe como essa tarefa era complexa, onde era necessário manipular métodos void e passar constantes para determinar  qual parte gostaríamos de alterar, aqui basta chamar o método plus desejado de forma fluente, veja o exemplo:

LocalDate localDate3         = LocalDate.now().plusDays(1).plusMonths(1);
LocalDateTime localDateTime3 = LocalDateTime.now().plusDays(1).plusMonths(1).plusHours(2);

Subtraindo dias, meses e horas

Da mesma forma que acontece a adição de valores,  podemos também subtrair dados de diferentes parte do período:

LocalDate localDate4       = LocalDate.now().minusDays(1).plusMonths(1);
LocalDateTime localDateTime4 = LocalDateTime.now().minusDays(1).minusMonths(1).minusHours(2);
LocalTime localTime4       = LocalTime.now().minusHours(1);

Criando objetos específicos

Um recurso interessante é quando criamos uma data com valores específicos, onde cada tipo possui métodos fábricas para construção dos objetos:

LocalDate localDate5       = LocalDate.of(2018, 07, 22);
LocalDateTime localDateTime5 = LocalDateTime.of(2018, 07, 22, 10, 15, 30);
LocalTime localTime5       = LocalTime.of(10, 35, 12);

Realizando parse de String em Datas

Uma das situações mais comuns é a operação de parse, que consiste em pegar uma data como String e transformar para a classe de Período correspondente:

LocalDate localDate6       = LocalDate.parse("2018-07-22", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
LocalDateTime localDateTime6 = LocalDateTime.parse("2018-07-22 10:35:10", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LocalTime localTime6       = LocalTime.parse("11:40:02", DateTimeFormatter.ofPattern("HH:mm:ss"));

Recuperando partes especificas de um objeto

Outro recurso interessante e muito utilizando é quando temos que recuperar uma parte especifica do objeto, podendo ser ano, mês, dia, hora, minuto, segundo:

int year    = LocalDate.now().getYear();
Month month = LocalDateTime.now().getMonth();
int hour    = LocalTime.now().getHour();

Comparando com os métodos isAfter, isBefore e isEqual

Com frequência temos que comparar objetos Data, analisando se um período é maior, menor ou igual ao outro, para isto temos métodos utilitários que facilitam esse tipo de ação, veja abaixo:

LocalDate localDate8 = LocalDate.now();
LocalDate localDate9 = LocalDate.now().minusDays(1);
  
boolean isAfter  = localDate8.isAfter(localDate9);   //true
boolean isBefore = localDate8.isBefore(localDate9); //false
boolean isEqual  = localDate8.isEqual(localDate9); //false

Capturando Diferenças entre LocalDate com classe Period

É comum precisar saber a diferença entre dois objetos Data, aqui temos a classe Period que possui vários métodos utilitários para esta finalidade, esta classe representa o tempo em anos, meses e dias, vamos testar o método between que recupera a diferença entre dois objetos LocalDate, veja abaixo:

LocalDate localDate10 = LocalDate.now();
LocalDate localDate11 = LocalDate.now().plusDays(2);
  
Period period1 = Period.between(localDate10, localDate11); 

Capturando Diferenças com a Enum ChronoUnit

A Enum ChronoUnit é utilizada para manipular Tempos, com ela podemos manipular tempos de  diferentes formas, podemos utiliza-la em conjunto com LocalDate, LocalDateTime e LocalTime, segue o exemplo:


LocalDateTime localDateTime12 = LocalDateTime.now();
LocalDateTime localDateTime13 = LocalDateTime.now().plusDays(2);
  
long periodAsMinutes = ChronoUnit.MINUTES.between(localDateTime12, localDateTime13);
long periodAsHours  = ChronoUnit.HOURS.between(localDateTime12, localDateTime13);
long periodAsDays = ChronoUnit.DAYS.between(localDateTime12, localDateTime13);

A API java.time possui uma porção de outros métodos e classes que podemos utilizar no decorrer dos projetos, trabalhar com datas, períodos, tempos, é praticamente obrigatórios em 90% dos sistemas.

A maioria dos frameworks do Mundo Java como Spring, Hibernate, JSF, já fornecem suporte full para o uso da API.

Até mais.

Código fonte

Referências

Instalando o Apache Spark e utilizando o Spark Shell

Olá pessoal, hoje iremos conhecer e instalar a ferramenta para processamento de dados Apache Spark, esta é uma ferramenta que atualmente vem sendo muito utilizada em ambientes de manipulação de grande quantidade de dados.

O Que é BigData

BigData é com certeza uma das palavras mais faladas em tecnologia nos últimos anos, e com isso temos diferentes significados espalhados pelas mais variadas fontes, mas basicamente BigData pode ser resumido em:
  • Volume: Grande quantidade de dados;
  • Variedade: Dados variados, sendo de tipos e fontes diferentes;
  • Velocidade: Dados crescendo/aumentando em alta velocidade.
Quando manipulamos uma grande quantidade de dados, começam a surgir desafios do mesmo tamanho, tais como performancecapacidadearmazenamentoescalabilidade, entre outros, e para esses novos desafios foram surgindo várias ferramentas, entre elas: Hadoop, Spark, NoSQL, Hive, entre outras.

Conhecendo o Spark

Como falamos anteriormente o Apache Spark foi uma dessas ferramentas que surgiram para resolver desafios enfrentados em cenários de BigData e Análise de Dados, a sua finalidade é realizar o processamento de uma grande quantidade de dados de forma escalável e com alta performance.

O site oficial da ferramenta é o https://spark.apache.org/

O Spark foi desenvolvido utilizando a linguagem Scala,  e pode ser utilizado com as linguagens ScalaPython ou Java, no site de exemplos temos uma variedade de exemplos de códigos em ambas as linguagens mencionadas, o intuito de poder utilizar diferentes linguagens, é que estas são as mais utilizadas em ambientes de grande quantidade de dados, além de fornecer opções para o desenvolvedor de acordo com seu skill.

Download do Spark

O primeiro passo é acessar https://spark.apache.org/downloads.html aqui encontramos todos os detalhes para o correto funcionamento da ferramenta, atualmente o Spark encontra-se na versão 2.3.0.

Site de download oficial do Apache Spark.

Um ponto importante aqui é que devemos ter o Java instalado na máquina, de acordo como site oficial, a versão da JVM recomendada é a 8.

O processo de instalação é o mesmo independente do Sistema Operacional, seja ele Linux, Windows ou Mac, basta efetuar o download e realizar a descompactação com um utilitário de preferência.

Como foi dito, após efetuar o download, basta descompactar em um diretório de sua preferência e teremos a seguinte estrutura:

Estrutura do Apache Spark após descompactação.

 Um ponto importante é a configuração da variável de ambiente chamada SPARK_HOME com o valor do diretório de instalação do Spark, isso é importante porque alguns utilitários do Spark utilizam esta variável como base para execução.


Conhecendo o Spark Shell

O Spark disponibiliza diversos shells, com eles podemos escrever códigos diretamente na linha de comando e acompanhar a execução, estes consoles estão disponíveis para Scala Python.

Como exemplo, vamos executar o console padrão que é o console chamado spark-shell onde você pode escrever códigos em Scala, o executável fica dentro do diretório bin/spark-shell.

Chamada do utilitário spark-shell

Ao executar teremos a seguinte resultado no terminal:

Console para execução de código Scala.

Neste console podemos utilizar todas as funcionalidades do Spark utilizando a linguagem Scala, geralmente este console é utilizado mais a critério de testes, porque para um grande projeto é recomendado o uso de alguma IDE ou ambiente que possua ferramentas de debug e testes.

O console possui alguns objetos implícitos disponíveis para uso, um deles é o principal, o SparkContext, este é o contexto responsável pela criação dos RDD que é a estrutura que utilizamos para manipular os dados dentro do Spark, para ver o SparkContext basta digitar no terminal sc:

Exibindo o SparkContext no console.

Após estes passos já temos o Apache Spark instalado e configurado.

Até a próxima.


Referências

Criando e Executando Funções no MongoDB

Olá pessoal, hoje iremos ver como realizar a criação e execução de funções dentro de uma base no banco de dados MongoDB.


Conhecendo o MongoDB

Nos dias atuais o tema NoSQL vem sendo muito discutido, muitas empresas vem adotando este paradigma de armazenamento, mas como toda tecnologia existem prós e contras, para entender bem o tema recomento a leitura do livro NoSQL Essencial (NoSQL Destilled) dos autores Promod J. Sadalage e Martin Fowler, o livro mostra características de aplicações, modelos de NoSQL, entre outras detalhes importantes sobre adoção de qualquer banco desse segmento.

O MongoDB é um banco de dados NoSQL baseado no modelo de documentos, onde cada registro é armazenado em forma de um documento BSON, uma característica muito legal do MongoDB é justamente trabalhar neste formato, porque o formato JSON é amplamente utilizado pela maioria dos desenvolvedores, sendo assim o entendimento da estrutura de armazenamento se torna simples.

Criando Funções no MongoDB

O MongoDB permite a criação de funções JavaScript dentro do banco, com isso podemos criar funções e executa-las manipulando nossas coleções e seus dados.

Um ponto muito importante que devemos ressaltar, seguindo boas práticas de desenvolvimento, devemos evitar de adicionar lógicas de negócio dentro dessas funções, o uso de funções deve ser efeito com a finalidade de manipular informações, evitando criar as famosas "Procedures" do mundo SQL.

No próprio site oficial do MongoDB, existe uma nota informando para usar as funções com cautela e evitar de acrescentar lógicas de negócio dentro do banco, pois existem limitações na execução de código JavaScript sobre o MondoDB.

https://docs.mongodb.com/manual/tutorial/store-javascript-function-on-server/index.html
(09/04/2018 ás 19:00)


Calculando o Tamanho de um Documento BSON

Para termos um exemplo do uso de funções no MongoDB, vamos criar uma função que retorna o tamanho de um documento de uma determinada coleção, para realizar a criação de funções, podemos utilizar a linha de comando logado na devida base de dados, ou utilizar alguma ferramenta como o Robomongo (Robo 3T), a função irá ficar como abaixo:


1
2
3
4
5
6
7
8
function(collectionName, _id) {
    
    var data = db.getCollection(collectionName).findOne({_id:_id});
    
    var result = Object.bsonsize(data);
    
    return result;
}

Perceba que é puro código JavaScript, na linha 1, temos a declaração da função, onde receberemos como argumento o collectionName (nome da coleção) e o _id (chave da coleção), na linha 3, executamos a busca do documento utilizando como critério o _id, na linha 5, utilizamos a função Object.bsonsize(), que retorna o tamanho em bytes do documento.

Para criar a função no Robomongo, basta seguir como abaixo:

Criando uma função utilizando a ferramenta Robomongo.

Existem outras maneiras de criar funções no MongoDB, para mais detalhes veja a documentação oficial: https://docs.mongodb.com/manual/tutorial/store-javascript-function-on-server/index.html


Executando uma Função

Agora vamos executar a função da seguinte maneira:

1
2
3
db.loadServerScripts();

documentSize("collection_teste", "123456");

Na linha 1, carregamos os scripts para que possam ser executados, na linha 3, executamos a função chamada documentSize(<<nome_coleção>>, <<valor_da_chave>>)

Executando no Robomongo temos o seguinte resultado:

Execução da função no Robomongo.

Na imagem acima foi executada a função retornando o devido resultado, as funções no MongoDB podem ajudar em atividades comuns na manipulação dos dados.

Até a próxima.

Referências