An Interest In:
Web News this Week
- April 1, 2024
- March 31, 2024
- March 30, 2024
- March 29, 2024
- March 28, 2024
- March 27, 2024
- March 26, 2024
Brincando com Ecto.Query
Introduo
Sejam bem-vindos, fico imensamente feliz com seu interesse em aprender um pouco mais sobre o Ecto e suas funcionalidades do modulo Ecto.Query
para construir queries SQL
Vamos usar o projeto do post Introduo ao Ecto para brincarmos um pouco com as queries sql.
Recomendo ler o projeto anterior sobre Ecto
para melhor compreenso.
Schemas utilizado para este projeto:
Mdulo User
defmodule Ecto4noobs.User do use Ecto.Schema import Ecto.Changeset alias Ecto4noobs.Movie schema "users" do field(:name, :string) field(:email, :string) field(:age, :integer) belongs_to(:movie, Movie) endend
Mdulo Movie
defmodule Ecto4noobs.Movie do use Ecto.Schema import Ecto.Changeset alias Ecto4noobs.User schema "movies" do field(:title, :string) field(:director, :string) field(:year, :integer) has_many(:users, User) endend
Relao Belongs To/Has Many
Vamos iniciar com dois schemas: User e Movie. Vamos implementar uma relao belongs_to/has_many
entre os dois: Um filme tem vrios (has many) usurios e um usurio pertence a (belongs to) um filme.
Schema Belongs To
Belongs To utiliza a chave estrangeira para tornar o filme associado a um usurio disponvel quando executamos a consulta.
Schema Has Many
Has Many no adiciona dados ao banco de dados por si s. O que ela faz utilizar uma chave estrangeira
no schema associado (users).
Listando os filmes
from(m in Movie) |> Repo.all()
Se notarmos, veremos que temos a seguinte mensagem: NotLoadAssociation
. Caso a gente queria listar os usurios
juntamente aos filmes
, apenas essa query
no o suficiente.
Para carregas as associaes, faremos:
query = from(m in Movie, preload: [:users]) |> Repo.all()
Exemplos de query com filtros where:
Buscando os usurios com idade menos que 20.
query = from(u in User, where: u.age < 20)
U
representa uma linha da tabela User
e em seguida a gente passa a condio que queremos filtrar, que no caso queremos filtrar a idade que for menor que 20.
Antes de continuarmos vamos aprender um pouco sobre SQL JOIN
O que um JOIN?
Bom, o join combina duas tabelas atravs de alguma chave ou valor comum entre elas.
Existem alguns tipos diferentes de JOIN:
INNER JOIN: um comando que permite a seleo de informaes em diferentes tabelas, desde que a informao em questo seja compartilhada por ambas.
LEFT JOIN: um comando que retorna todos os registros da tabela esquerda e os registros correspondentes da tabela direita.
RIGHT JOIN: Ao contrrio do LEFT JOIN, o comando RIGHT JOIN retorna todos os dados encontrados na tabela direita. Porm, se no tiver dados associados entre as tabelas esquerda e direita, ele retorna valores nulos.
Usando INNER JOIN
query = from(u in User, inner_join: m in Movie, on: u.movie_id == m.id, select: [m.title, u.name])
Neste exemplo, estamos buscando os filmes e o nome do usurio que cada um recebeu. Para isso, comeamos a nossa query na tabela User
, depois fazemos um inner_join
na tabela de filmes
e cujo a condio do ID do filme do usurio igual ao ID do filme. Por fim, a gente faz a seleo dos campos que queremos mostrar.
Usando LEFT JOIN
query = from(m in Movie, left_join: u in User, on: u.movie_id == m.id, where: u.name == "Floki O Gato" and m.title == "Um Sonho de Liberdade", select: [m.title, u.name])
Neste exemplo, buscamos filmes que contm o usurio "Floki O Gato". Para isso, comeamos a query na tabela Movie, depois fazemos um left_join
na tabela User
e cujo a condio do ID do filme do usurio igual ao ID do filme eu busco por usurio "Floki O Gato" onde o titulo do filme "Um Sonho de Liberdade". Por fim, a gente faz a seleo dos campos que queremos mostrar.
Usando LEFT EXCLUDING JOIN
Filmes que no tiveram nenhum usurio
Usando RIGHT JOIN
query = from(m in Movie, right_join: u in User, on: u.movie_id == m.id, select: [m.title, u.name])
Neste exemplo, estou buscando os filmes com o usurio que foi recebido.
Usando RIGHT EXCLUDING JOIN
Buscar os filmes com os usurio que cada um recebeu
query = from(m in Movie, right_join: u in User, on: u.movie_id == m.id, where: not is_nil(u.name), select: [m.title, u.name])
Fragment
Forma de chamar funes em SQL puro no Ecto
query = from(m in Movie, select: fragment("upper(?)", m.title))
Estamos fazendo uma listagem de ttulos de filme em uppercase fragment(upper)
que uma funo do Postgres.
OU
title = "O Poderoso Chefo"query = from(m in Movie, where: m.title == ^title, select: fragment("upper(?)", m.title))
Quando queremos colocar um valor de uma varivel dentro da querie a gente precisa colocar operador pinar (^)
se no, dar erro de compilao.
LIKE
Forma de busca por campo de texto
title = "O"query = from(m in Movie, where: like(m.title, ^"#{title}%"), select: fragment("upper(?)", m.title))
Filtrando ttulos de filme que comeam com a letra O
.
Ento, nesse nosso exemplo quero buscar os filmes que comeam com O, ento eu uso a funo do Ecto LIKE
passando o campo de texto que eu quero interpolar e o sinal de pinar, por fim o porcent %
que para dar match
em qualquer termo.
E isso! =)
Concluso
Muito obrigado pela leitura at aqui e espero ter ajudado de alguma forma. Tem alguma sugesto ou encontrou algum problema? por favor deixe-me saber.
Original Link: https://dev.to/rohlacanna/brincando-com-ectoquery-4paj
Dev To
An online community for sharing and discovering great ideas, having debates, and making friendsMore About this Source Visit Dev To