Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Suissa

Pensando em MongoDB com SQL ‘s comuns

Recommended Posts

Neste artigo vou mostrar como podemos pensar nas consultas para o MongoDB apartir das nossas sqls normais. Para entendermos melhor como se faz uma consulta no MongoDB vamos olhar esse código:

$filter = array( “nome” => “Jean Nascimento” );
$cursor = $collection->find($filter);
foreach ($cursor as $obj) { echo $obj["nome"]. ” – ” . $obj["_id"] . “<br />”; }
Percebe-se que a variável $filter receberá um parametro que filtrará nossa busca, no caso ela buscará os objetos que possuem o nome = ‘Jean Nascimento’. A variável $cursor receberá o resultado através da função find(). E o foreach mostrará os elementos achados.

Vamos começar com um select básico que pesquisará tudo onde o nome for igual a Jean Nascimento: select * from tabela where nome = ‘Jean Nascimento’

Nosso correspondente em MongoDB será: $filter = array( “nome” => “Jean Nascimento” );

 

Agora vamos usar o operador LIKE do SQL para procurar pelas ocorrências que comecem com J e possuam 4 caracteres como Jean, João, José: select * from tabela where nome LIKE ‘J___ Nascimento’

O correspondente em MongoDB será:

$filter = array( “nome” => new MongoRegex(‘/^J[a-Z]{3} Nascimento/i’ );

Como vimos acima, devemos usar a função MongoRegex para filtrar campos com string no MongoDB. Pelo nome fica fácil de entender que ela se utiliza de expressões regulares para procurar as strings. Aconselho a terem pelo menos uma base de expressões regulares para poderem utilizar do poder desse filtro.

Vamos a mais uns exemplos.

Este select pesquisará todos os nomes que possuam Nasc no seu valor: select * from tabela where nome LIKE ‘%Nasc%’

O seu correspondente no nosso filtro será: $filter = array( ‘title’ => new MongoRegex(‘/.Nasc./i’) );

Agora além dos operadores básicos de igualdade e LIKE, podemos utilizar outros operadores como: IN, NOT IN, >, >=, <, <= e <>.

Vou dar um exemplo de cada:

SQL: select * from usuarios where UsuarioID IN (2,14,16)
MongoDB: $filter = array(“UsuarioID” => array(‘$in’ => array(2,14,16)));

SQL: select * from usuarios where UsuarioID NOT IN (2,14,16)
MongoDB: $filter = array(“UsuarioID” => array(‘$nin’ => array(2,14,16)));

SQL: select * from usuarios where UsuarioID > 33
MongoDB: $filter = array(“UsuarioID” => array(‘$gt’ => 33));


SQL: select * from usuarios where UsuarioID >= 33
MongoDB: $filter = array(“UsuarioID” => array(‘$gte’ => 33));

SQL: select * from usuarios where UsuarioID < 33
MongoDB: $filter = array(“UsuarioID” => array(‘$lt’ => 33));

SQL: select * from usuarios where UsuarioID <= 33
MongoDB: $filter = array(“UsuarioID” => array(‘$lte’ => 33));

SQL: select * from usuarios where UsuarioID <> 33
MongoDB: $filter = array(“UsuarioID” => array(‘$ne’ => 33));
E se nós quisermos inserir algum dado no MongoDB? Imagine a query: insert into usuario(login, email) VALUES(‘sissa’, ‘jnascimento@gmail.com’)

Para utilizarmos o insert no MongoDB com a sua extensão habilitada no PHP, criamos o array com os valores que vamos inserir:

$query = array(

‘usuario’ => “suissa”,

‘email’ => “jnascimento@gmail.com”

 

);

 

Depois disso é só chamar o insert.

$db->collection->insert($this->query);

Essa instrução equivale à sql: insert into usuario(UsuarioID, Usuario, Email) VALUES(1, “suissa”, “jnascimento@gmail.com“)

 

Atualizar registros no MongoDB é praticamente igual, porem, precisamos passar o paramentro da busca. Apesar desse exemplo simples, e mais comum, os filtros dos selects muitas vezes devem ser utilizados para fazer atualizações nos registros.

$db->collection->update(array(‘_id’ => new MongoID($mongo_id)), array(‘$set’ => array(‘Tarefa’ => ‘Terminar artigo’)));
Como podemos perceber a primeira parte, array(‘_id’ => new MongoID($mongo_id)), é o filtro da busca podendo ser modificado para filtrar por qualquer campo existente. A segunda parte, array(‘$set’ => array(‘Tarefa’ => ‘Terminar artigo’)), nos diz respeito ao valor que vamos alterar .

 

 

Agora a seguinte sql: update tarefas set Tarefa=’Terminar artigo’ where Usuario=’suissa’

Ficará:

$db->collection->update(array(‘Usuario’ => ‘suissa’), array(‘$set’ => array(‘Tarefa’ => ‘Terminar artigo’)));

O operador $set, pode ser alterado para $inc, que fará com que o MongoDB incremente automaticamente o valor especificado para mais ou para menos:

$db->collection->update(array(‘_id’ => new MongoID($mongo_id)), array(‘$inc’ => array(‘Visitas’ => 1), false); //incrementa com +1
$db->collection->update(array(‘_id’ => new MongoID($mongo_id)), array(‘$inc’ => array(‘Visitas’ => 5), false); //incrementa com +5
$db->collection->update(array(‘_id’ => new MongoID($mongo_id)), array(‘$inc’ => array(‘Visitas’ => -1), false); //retira 1
$db->collection->update(array(‘_id’ => new MongoID($mongo_id)), array(‘$inc’ => array(‘Visitas’ => -5), false); //retira 5
Excluir um registro:

$db->collection->remove(array(‘_id’ => new MongoID($mongo_id)));
$db->collection->remove(array(‘Usuario’ => ‘suissa’));
Também levando em conta que você pode usar algumas propriedades usadas no select para remover registros em grupos.

 

Com isso nós já estamos aptos a programar e interagir com o MongoDB de inúmeras formas.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Muito bons os exemplos. Deixou bem claro a forma de utilização.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Isso é muito legal, fazer buscas com expressões regulares :)

Compartilhar este post


Link para o post
Compartilhar em outros sites

desculpe a ignorancia, mas faz join?

 

Não, giesta, não faz join.

 

Contudo, você pode ter referências dentro de suas coleções, nesse post foi ilustrada a situação.

 

Existem duas situações:

 

1. Você tem um conjunto de informações que não necessitam de uma coleção própria:

 

Caso http://forum.imasters.com.br/public/style_emoticons/default/seta.gif Lista de emails para um único usuário:

 

MySQL:

 

Table User
==========
idUser, userName
----------
idUser 	MEDIUMINT UNSIGNED
userName 	VARCHAR

Table Email
===========
idEmail, idUser, email
-----------
idEmail 	MEDIUMINT UNSIGNED
idUser 	MEDIUMINT UNSIGNED
email VARCHAR

INSERT INTO `User`(`userName`) VALUES('João Batista Neto'),('giesta');

 

INSERT INTO `Email`(`idUser`,`email`) VALUES
(1,'neto@example.com'),
(1,'joaoneto@test.com'),
(1,'joaobatistaneto@gmail.com'),
(2,'giesta@imasters.com'),
(2,'gista@test.com'),
(2,'giesta@hotmail.com');

 

SELECT `u`.`userName`,`e`.`email` FROM `User` AS `u`
LEFT JOIN `Email` AS `e` USING(`idUser`);

 

mysql> SELECT `u`.`userName`,`e`.`email` FROM `User` AS `u`
	-> LEFT JOIN `Email` AS `e` USING(`idUser`);
+-------------------+---------------------------+
| userName 	| email 	|
+-------------------+---------------------------+
| João Batista Neto | neto@example.com 	|
| João Batista Neto | joaoneto@test.com 	|
| João Batista Neto | joaobatistaneto@gmail.com |
| giesta 	| giesta@imasters.com |
| giesta 	| gista@test.com 	|
| giesta 	| giesta@hotmail.com	|
+-------------------+---------------------------+
6 rows in set (0.00 sec)

MongoDB:

 

> db.user.save( {
... name : 'João Batista Neto',
... emails : [
...	{ email : 'neto@example.com' },
...	{ email : 'joaoneto@test.com' },
...	{ emails : 'joaobatistaneto@gmail.com' }
... ]
... } );
> 
> db.user.save( {
... name : 'giesta',
... emails : [
...	{ email : 'giesta@imasters.com' },
...	{ email : 'giesta@test.com'},
...	{ email : 'giesta@hotmail.com'}
... ]
... } );

> db.user.find()
{ "_id" : ObjectId("4c7787d792830ef35422d607"), "name" : "João Batista Neto", "emails" : [
 	{
 	"email" : "neto@example.com"
 	},
 	{
 	"email" : "joaoneto@test.com"
 	},
 	{
 	"emails" : "joaobatistaneto@gmail.com"
 	}
] }
{ "_id" : ObjectId("4c7787d992830ef35422d608"), "name" : "giesta", "emails" : [
 	{
 	"email" : "giesta@imasters.com"
 	},
 	{
 	"email" : "giesta@test.com"
 	},
 	{
 	"email" : "giesta@hotmail.com"
 	}
] }

Recuperando apenas os emails do domínio @test.com

 

MySQL:

 

mysql> SELECT `u`.`userName`,`e`.`email` FROM `User` AS `u`
	-> LEFT JOIN `Email` AS `e` ON( (`e`.`idUser`=`u`.`idUser`) AND (`e`.`email` LIKE '%@test.com'));
+-------------------+-------------------+
| userName 	| email 	|
+-------------------+-------------------+
| João Batista Neto | joaoneto@test.com |
| giesta 	| gista@test.com 	|
+-------------------+-------------------+
2 rows in set (0.00 sec)

MongoDB:

 

> map = function(){
... 	var obj = this;
... 
... 	this.emails.forEach(
... 	 	function ( item ){ 
... 	 	 	if ( /[^@]+@test\.com/.test( item.email ) ){
... 	 	 	 	emit( obj._id , { name : obj.name , email : item.email } );
... 	 	 	}
... 	 	}
... 	);
... }
> reduce = function (key, values) {
... 	var ret = {};
... 
... 	if ( values.length ){
... 	 	ret.name = values[ 0 ].name;
... 	 	ret.emails = [];
... 
... 	 	for (var i = 0, t = values.length; i < t; ++i) {
... 	 	 	ret.emails.push({email:values[i].email});
... 	 	}
... 	}
... 
... 	return ret;
... }

> db[ db.user.mapReduce( map , reduce ).result ].find();
{ "_id" : ObjectId("4c7787d792830ef35422d607"), "value" : { "name" : "João Batista Neto", "emails" : [ { "email" : "joaoneto@test.com" } ] } }
{ "_id" : ObjectId("4c7787d992830ef35422d608"), "value" : { "name" : "giesta", "emails" : [ { "email" : "giesta@test.com" } ] } }

;)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ótimas considerações como sempre!

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.