Seguindo a ideia inicial deste diário, que é anotar o que eu aprendo no dia a dia, aqui vai o que aprendi esta semana ;)

Buscas no MongoDB sem diferenciação entre maiúsculas e minúsculas

No MongoDB realizamos buscas com o comando find() utilizando uma query, desta forma:

db.collection.find({Nome: 'MongoDB'})

Porém neste caso, a busca retornaria apenas resultados cujo valor do campo nome fosse exatamente MongoDB.

Mas descobri através de uma aula do Be MEAN que podemos tornar essa busca case insensitive, ou seja, fazer o mongo ignorar a diferença entre maiúsculas e minúsculas, usando regex.

Então nossa busca com regex ficaria assim: db.collection.find({Nome: /mongodb/i})

Isto faz com que obtenhamos documentos com o nome mongodb, MongoDB, mongoDB e assim por diante.

Qual a diferença entre usar diretivas <ion-*> e classes no Ionic Framework?

Estou desenvolvendo um app para a faculade com Ionic, e me veio essa dúvida, qual a diferença entre usar <ul class="list"> e <ion-list> por exemplo?

A resposta veio dos fóruns: com as classes só temos a estilização, já as diretivas nos dão mais funcionalidades.

Este comentário no código fonte do Ionic exemplifica bem:

The containing element requires the list class and each list item requires the item class. However, using the ionList and ionItem directives make it easy to support various interaction modes such as swipe to edit, drag to reorder, and removing items.

Utilizar o kramdown no seu blog Jekyll lhe dá mais opções

Escrevendo um post, senti a necessidade de fazer uma lista de definições e também gostaria de usar notas de rodapé. O Jekyll no GitHub vem com o processador redcarpet por padrão.

Mas dando uma googleada descobri que o kramdown me dava essas opções a mais e para utilizar com o jekyll bastava mudar markdown: redcarpet para markdown: kramdown

Concluindo

Estou gostando de fazer este diário, especialmente porque eu aprendo muito mais quando eu crio conteúdo do que quando eu consumo. Afinal não quero escrever besteira, então sempre tento dar uma pesquisada antes de falar sobre algo.

E é claro que bate aquela vontadezinha de que alguém leia seu texto, e eu acho que é esse tipo de pretensão que me faz ser menos produtivo com o blog, porque sempre que penso em escrever algo, fico imaginando qual categoria utilizar, como organizar as tags, como não deixar o post simples demais… E todas estas coisas me seguram um pouco na hora de escrever e publicar meus textos.

Mas o jeito é se manter firme na proposta e insistir nela, por isso pode ser que esse diário seja uma pequena bagunça. E afinal desde quando um diário é organizado?

Às vezes acho que escrevo demais para o que este projeto se propõe, mas não consigo parar. Mas pode ser que isso seja bom, vai formar a personalidade diferenciada deste blog :)

Rapaz, esse curso tá ficando cada vez mais denso! E isso é bom, afinal quanto mais conhecimento melhor! Vou escrever bastante, então prepare-se:

Nessa aula foi recordado que para alterar um documento no MongoDB, temos dois comandos:

db.collection.save() e db.collection.update()

Modificando documentos com save()

A diferença básica entre os dois comandos é que com o save temos que buscar e guardar o objeto numa variável, e depoooois salvá-lo no banco, dessa forma:

Primeiro buscamos o objeto: var p = db.pokemons.findOne({name:/pikachu/i})

Temos que usar findOne() pois o find() não retorna o objeto em si, mas sim um cursor. Me corrija nos comentários se eu estiver errado!

Então p terá o seguinte conteúdo:

{
  "_id": ObjectId("5650c5c8c36927f637e6ce10"),
  "name": "Pikachu",
  "description": "Rato elétrico bem fofinho",
  "type": "electric",
  "attack": 55,
  "height": 0.4
}

Agora podemos alterar um de seus valores, como por exemplo: p.attack = 50.

E daí salvamos com db.pokemons.save(p). Isso altera o valor do attack do Pikachu no banco.

Modificando documentos com update()

Já com update() é um pouco diferente. Primeiro, o update() recebe três parâmetros:

  • query (geralmente com o _id do documento que queremos modificar)
  • update (a modificação)
  • options (parâmetro opcional, veremos mais pra frente)

Com esta sintaxe: db.collection.update(query, update, options).

Podemos então criar uma query var query = {"_id": ObjectId("5652574334d59f7ade6bf57e")} que no meu caso retornará este documento:

{
  "_id": ObjectId("5652574334d59f7ade6bf57e"),
  "name": "Testemon",
  "attack": 8000,
  "defense": 8000,
  "height": 2.1,
  "description": "Pokemon de teste"
}

e um mod (parâmetro update):

var mod = {description: "Teste de modificação"}

Então passamos os parâmetros ao comando update(): db.pokemons.update(query, mod).

Executamos o comando, e ao buscar o documento no banco com db.pokemons.find(query) para ver como ficou temos este retorno:

{
  "_id": ObjectId("5652574334d59f7ade6bf57e"),
  "description": "Teste de modificação"
}

Opa! O update() não só modificou a description do nosso documento como removeu os outros campos. Isso acontece porque passamos o parâmetro de update sem usar um operador de modificação.

De acordo com a documentação do mongo:

  • O comando update() substitui o documento que corresponde a nossa query pelo documento do nosso segundo parâmetro, no nosso caso o mod
  • O comando update() não altera o _id do documento
  • O comando update() não altera múltiplos documentos de uma vez

Então para alterarmos um campo apenas, sem substituir o documento inteiro, temos de usar nossos…

Operadores de Modificação

Que são:

$set
muda o valor de um campo, criando-o caso não exista
uso: { $set: { campo: valor } }
$unset
remove campo
uso: { $unset: { campo: 1 } } colocamos 1 (true) para remover o campo
$inc
incrementa o valor do campo com a quantidade especificada
para decrementar, usar valor negativo
uso: { $inc: { campo: 1 } }

Exemplo:

var mod = {$inc: { attack: 1 }}
db.pokemons.update(query, mod)

O código acima vai apenas incrementar do campo attack do nosso registro em 1, e manter todos os outros campos intactos.

A lista segue, mas para não deixar o post muito longo vou parar por aqui, que é até onde foi abordado na aula. Mas o restante está na documentação :)

No próximo post eu continuo!

Eu disse que o curso estava ficando denso mas nem eu sabia o quanto… Já escrevi tanto e não acabou ainda! Por isso vou parar por aqui, assim não abordo muitos assuntos num post só.

Então assine meu feed RSS e/ou me siga no facebook e aguarde ;)

Mais uma aula do Be MEAN, e hoje aprendemos o que seria a segunda operação básica em banco de dados, ou seja, o READ do CRUD.

Aprendemos dois comandos para recuperar dados no mongodb:

  • db.find()
  • db.findOne()

O UUD (Universal Unique Identifier) de um objeto

Quando inserimos um objeto no mongodb, é gerado um _id automaticamente (e não tem nada de autoincremento). O _id tem esse formato:

  • 4-bytes que representam os segundos desde a época Unix,
  • 3-bytes para o identificador de máquina,
  • 2-bytes com o ID do processo,
  • e 3-bytes para um contador, começando com um valor aleatório.

Na prática, o _id se parece com isto: 507f1f77bcf86cd799439011

Se fosse escrito em binário, seria um número de 96 dígitos. Tipo assim: 010100000111111100011111011101111011110011111000011011001101011110011001010000111001000000010001

Uma coisa que pensei nesse momento foi: até quantos anos será que dá pra usar esse esquema de 4 bytes para represntar os segundos do UNIX? Pelos meus cálculos, dá 21 séculos (me corrija se eu estiver errado), ufa, dá pra usar este esquema por muito tempo então.

Voltando ao comando find()

O find aceita dois parâmetros, query (cláusulas) e fields (campos), dessa maneira:

db.collection.find({clausulas}, {campos})

Para facilitar, é recomendável criar variáveis especificando um JSON para fazer a busca, desse jeito:

var query = {Nome: 'Fulano'}

Daí passamos o parâmetro pro find assim:

db.collection.find(query)

O parâmetro fields define quais campos queremos. Para usá-lo devemos dizer o nome do campo junto com o valor 1, se quisermos que a busca retorne este campo, ou 0 caso não queiramos este campo.

Por exemplo, caso queiramos fazer uma busca que retorne os campos Nome e Idade de um objeto:

var fields = {Nome: 1, Idade: 1} db.collection.find(query, fields)

O retorno seria algo como:

{
  "_id": ObjectId("564220f0613f89ac53a7b5d0"),
  "Nome": "Fulano",
  "Idade": "25"
}

Perceba que o _id foi retornado mesmo sem ter sido especificado. É porque ele é o único campo que é retornado sempre. Caso não queiramos que ele seja retornado, basta especificá-lo com o valor 0:

var fields = {Nome: 1, Idade: 1, _id: 0}

Operadores Aritméticos e Lógicos

Os operadores servem para obtermos apenas resultados que satisfaçam certa condição. Temos os seguintes operadores:

  • $lt (less than)
  • $lte (less than or equal)
  • $gt (greater than)
  • $gte (greater than or equal)

E dentre os lógicos temos:

  • $or
  • $nor (“ou sqn”)
  • $and

E o uso destes segue o formato dos seguintes exemplos:

  • var query = {height:{$lte:0.5}} para obter apenas resultados cujo campo height seja menor ou igual a 0.5
  • var query = {name:"bob", $nor:[{a:1}, {b:2}]} para obter resultados que tenham o campo name porém os valores de pelo menos um dos campos a e b não sejam 1 e 2 respectivamente.

Pode parecer meio difícil de entender, mas é só ler com calma e/ou mais de uma vez que fica fácil ;)

O JSON desse último exemplo, numa forma tabulada ficaria assim:

{
  "name": "bob",
  "$nor": [
    {
      "a": 1
    },
    {
      "b": 2
    }
  ]
}

Exemplo com o operador $and:

var query1 = { a: 1 };
var query2 = { b: { $gt: 5 } } ;

db.collection.find( { $and: [query1, query2] } )

Nesse caso somente são retornados resultados que satisfaçam as duas condições query1 e query2.

Operador existencial

Temos também o operador $exists, que retorna o objeto caso o campo exista. Por exemplo:

db.collection.find( { altura : { $exists : true } } );

Só retorna objetos nos quais existam o campo altura.

Conclusão

Basicamente esse foi o conteúdo da terceira aula. Espero que tenha sido útil pra você, e qualquer coisa comente abaixo ;)

Sabe quando você acha que algo é fácil e acaba perdendo algumas horas pra fazer? Pois é, foi assim comigo pra colocar esse blog no ar. Tem muitas coisas que quero fazer ainda pra deixar esse blog supimpa, mas como o que importa mesmo é o conteúdo, vou ajeitando as outras coisas com o tempo :)

Enfim, a ideia aqui é manter um diário de tudo que eu aprendo no dia a dia, relacionado a desenvolvimento, tecnologia, web, programação, frontend, e o que mais vier ;) (será que consigo finalizar o próximo parágrafo sem emoticon?)

Geralmente quando se começa um blog, você tem que ter certo domínio sobre o assunto, mas não me considero especialista em nenhum assunto. Na verdade, tenho muito, muito a aprender, e estou aprendendo tanto nos últimos meses que eu não posso deixar de registrar as notas em algum lugar. Além disso, pode ser muito útil para quem também está trilhando esse caminho, e principalmente para mim, que posso receber feedback de você, leitor. (ahá, não terminei com emoticon :P ops)

Aliás, o nome do blog é Todo dia algo novo.

Blogando com Jekyll

Voltando ao aspecto técnico do blog, algo que me ajudou muito foi os posts do Willian Justen:

E algumas coisas que quero fazer aqui no blog ainda:

  • Mudar essa fonte esquisita do título do site
  • Página de Séries e tags
  • Busca
  • Feed RSS

Já tem conteúdo

Por enquanto é isso, aliás, já tem três posts que eu tinha escrito antes:

Até logo ;)

Segunda aula de MongoDB e a coisa está ficando séria! Vou até fazer uma lista de comandos:

Comandos de hoje

  • use <collection> muda a base de dados em uso, cria se ainda não existir
  • db variável que aponta para a base de dados em uso
  • show dbs mostra as bases criadas
  • show collections mostra as coleções da base de dados em uso
  • db.createCollection() cria uma coleção vazia
  • db.collection.insert() (onde collection é a sua coleção) insere objetos
  • db.collection.find() executa uma query
  • db.collection.save() insere e salva
  • db.collection.findOne() executa uma query e retorna um objeto

Obs.: ao criar uma base de dados com o use, e este criar uma nova base de dados, ela não será exibida pelo show dbs, pois nada foi inserido nela ainda.

Cursors

Ao dar var cur = db.collection.find(), cur será um cursor, e caso haja documentos que possam ser iterados, podemos fazer um while(cur.hasNext()){print(tojson(cur.next()))} para mostrar os documentos.

Basicamente (pelo que entendi), NoSQL segue um modelo não relacional, e por isso pode tratar cada caso de forma mais eficiente, existem por exemplo bancos NoSQL para tratar de grafos, de docuemtos, etc.

Referência

Com tanto conteúdo novo, a documentação do mongo será sua melhor amiga :)