Lembrando da aula anterior quando falei que a busca com find
retorna um cursor onde você deve iterar nele para buscar seus dados, hoje veremos a diferença dele para o findOne
.
Como havia dito, o Mongoose irá converter esse cursor para Array
então sempre quando quisermos LISTAR algo iremos utilizar o find
.
CUIDADO
Mesmo você buscando diretamente com o _id
Esse _id
que vocês devem ter visto nos registros inseridos nada mais é que um UUID.
Ele também é conhecido como ObjectId
e ele é um tipo do BSON de 12-bytes, construído usando:
4-bytes: valor que representa os segundos desde a época Unix; 3-bytes: identificador de máquina; 2-bytes: ID do processo; 3-bytes: contador, começando com um valor aleatório. Sim essa porra é "universalmente única"!
O _id
é nossa chave primária, olha aí relational-guys, é com ele que fazemos consultas específicas, por favor não esqueça disso!!!
Para facilitar nossa vida iremos criar um JSON para nossa query, para isso iremos criar um JSON da seguinte forma:
var query = {name: 'Pikachu'}
Isso significa que iremos pesquisar apenas os Pokemons com o name
igual a Pikachu
.
Esse nosso objeto de query
tem a mesma funcionalidade do tão conhecido SELECT
dos bancos relacionais.
Eu já escrevi sobre isso em 2010 no iMasters - Como utilizar selects com MongoDB
Claro que é bem defasado e escrito ainda com PHP ehhehehhehhe.
Se o nosso JSON de query
é o WHERE
do relacional, logo o JSON fields
será o nosso SELECT
onde o mesmo irá selecionar quais campos desejados na busca da query
.
Para isso especificamos os campos desejados com 1
que significa TRUE
ou os campos indesejados com 0
que significa FALSE
suissacorp(mongod-3.0.6) be-mean-instagram> var query = {name: 'Pikachu'}
suissacorp(mongod-3.0.6) be-mean-instagram> var fields = {name: 1, description: 1}
suissacorp(mongod-3.0.6) be-mean-instagram> db.pokemons.find(query, fields)
{
"_id": ObjectId("564220f0613f89ac53a7b5d0"),
"name": "Pikachu",
"description": "Rato elétrico bem fofinho"
}
Fetched 1 record(s) in 1ms
db.colecao.find({ "campo" : { $lt: value } } ); Retorna documentos com valores menores que value.
db.colecao.find({ "campo" : { $lte: value } } ); Retorna documentos com valores menores ou igual que value.
db.colecao.find({ "campo" : { $gt: value } } ); Retorna documentos com valores maiores que value.
db.colecao.find({ "campo" : { $gte: value } } ); Retorna documentos com valores maiores ou igual que value.
Retorna documentos caso a cláusula OU for verdadeira, ou seja, se alguma das cláusulas forem verdadeiras
{ $or : [ { campo1 : valor } , { campo2 : valor } ] }
Vamos buscar os Pokemons que possuam OU o {name: Pikachu}
OU do tipo grama {type: 'grama'}
.
Retorna documentos caso a cláusula negação do OU for verdadeira, ou seja, retorna apenas documentos que não satisfaçam as cláusulas.
{ $nor : [ { a : 1 } , { b : 2 } ] }
Retorna documentos caso a cláusula E for verdadeira, ou seja, somente se todos as cláusulas forem verdadeiras.
{ $and: [ { a: 1 }, { a: { $gt: 5 } } ] }
db.colecao.find( { campo : { $exists : true } } );
Retorna o objeto caso o campo exista.
Antes de iniciar essa parte e já conhecendo sobre o update
, pois foi dado anteriormente que esta parte, vamos deixar todos os pokemons com 1 ataque igual.
var query = {}
var mod = {$set: {moves: ['investida']}}
var options = {multi: true}
db.pokemons.update(query, mod, options)
Pronto agora todos pokemons possuem um campo do tipo Array, para finalizar vamos adicionar 1 ataque para: Charmander, Squirtle e Bulbassauro.
var query = {name: /pikachu/i}
var mod = {$push: {moves: 'choque do trovão'}}
db.pokemons.update(query, mod)
var query = {name: /squirtle/i}
var mod = {$push: {moves: 'hidro bomba'}}
db.pokemons.update(query, mod)
var query = {name: /charmander/i}
var mod = {$push: {moves: 'lança-chamas'}}
db.pokemons.update(query, mod)
var query = {name: /bulbassauro/i}
var mod = {$push: {moves: 'folha navalha'}}
db.pokemons.update(query, mod)
O operador $in
retorna o(s) documento(s) que possui(em) algum dos valores passados no [Array_de_valores]
.
{ campo : { $in : [Array_de_valores] } }
Imaginemos que precisamos buscar todos Pokemons que possuam o ataque choque do trovão
, pois o investida
todos já possuem.
DICA: também pode usar REGEX aqui!
var query = {moves: {$in: [/choque do trovão/i]}}
db.pokemons.find(query)
Pronto com isso achamos apenas o Pikachu.
Retorna documentos se nenhum dos valores for encontrado.
{ campo : { $nin :[ [Array_de_valores] ] } }
Podemos trazer todos Pokemons que não possuem o ataque investida
.
var query = {moves: {$nin: [/choque do trovão/i]}}
db.pokemons.find(query)
Nesse caso todos, excluindo o Pikachu.
Retorna documentos se todos os valores foram encontrados.
{ campo : { $all :[ Array_de_valores ] } } )
Agora podemos buscar quais pokemons possuem os ataques investida
e hidro bomba
.
var query = {moves: {$all: ['hidro bomba', 'investida']}}
db.pokemons.find(query)
Dessa vez retornará apenas o Squirtle.
Retorna documentos se o valor não for igual.
{ campo : { $ne : valor} }
Podemos agora buscar todos os pokemons que não são do tipo grama
.
var query = {type: {$ne: 'grama'}}
db.pokemons.find(query)
DICA: Não aceita REGEX!!!!
Caso tente passar um valor como REGEX o MongoDb retornará esse erro:
Error: error: {
"$err": "Can't canonicalize query: BadValue Can't have regex as arg to $ne.",
"code": 17287
}
Retorna o objeto que não satisfaz a condição do campo, isso inclui documentos que não possuem o campo.
{ campo : { $not : { $gt: 666 } } }
Com esse operador iremos buscar os pokemons que não tem um attack
acima de 50.
var query = {attack: { $not : { $gt: 50 } } }
db.pokemons.find(query)
Percebeu que os documentos que não possuem o campo attack
também retornaram e que null
é menor que 50
.
E podemos usar REGEX para trazer todos os pokemons que não possuam o nome Pikachu
.
var query = { name : { $not : /pikachu/i } }
db.pokemons.find(query)
Usando o conhecimento sobre $and, $gte e $lt podemos realizar busca de datas.
Exemplo: Gostaria de puxar o cadastro de um pokemon que foi criado em 17/01/2016 cuja o nome seja 'Bulbassauro'.
Inserindo dados na coleção.
var pokemons = {'name':'Bulbassauro','description':'Chicote de trepadeira','type': 'grama', 'attack': 49, height: 0.4, created_at: new Date()};
db.pokemons.insert(pokemons);
WriteResult({ "nInserted" : 1 })
Depois da inserção buscaremos o campo created_at, que consta a data da criação do documento.
> var query = {$and: [{created_at: {$gte: new Date(2016, 0, 17), $lt: new Date(2016, 0, 18)}},{name:'Bulbassauro'}]};
> db.pokemons.findOne(query).pretty();
{
"_id" : ObjectId("569bb4441b2a879aee8fb0f1"),
"name" : "Bulbassauro",
"description" : "Chicote de trepadeira",
"type" : "grama",
"attack" : 49,
"height" : 0.4,
"created_at" : ISODate("2016-01-17T15:33:14.893Z")
}