Do you import Ecto.Query
? Do you have Ecto version 3 (Ecto 2.2.11 doesn’t support filter)?
# file: music_db/priv/repo/playground.exs
#
# http://www.pragmaticprogrammer.com/titles/wmecto
# https://pragprog.com/titles/wmecto/source_code
# http://media.pragprog.com/titles/wmecto/code/wmecto-code.zip
#
# pg_ctl -D /usr/local/var/postgres start
# mix format ./priv/repo/playground.exs
# mix run ./priv/repo/playground.exs
#
defmodule AppInfo do
def string() do
Application.loaded_applications()
|> Enum.map(&to_app_keyword/1)
|> Enum.sort_by(&map_app_name/1)
|> Enum.map_join(", ", &app_keyword_to_string/1)
end
defp to_app_keyword({app, _, vsn}),
do: {app, vsn}
defp app_keyword_to_string({app, vsn}),
do: Atom.to_string(app) <> ": " <> to_string(vsn)
defp map_app_name({app, _}),
do: app
end
defmodule Playground do
import Ecto.Query
alias MusicDB.Repo
alias MusicDB.{Album}
def play do
IO.puts(AppInfo.string())
# Ecto.Adapters.SQL.to_sql(:all, Repo, query)
from(a in Album,
join: g in assoc(a, :genres),
where: a.artist_id == 1,
select: %{
live: count(1) |> filter(g.name == "live"),
jazz: count(1) |> filter(g.name == "jazz")
}
)
|> Repo.all()
end
end
IO.inspect(Playground.play())
$ mix run ./priv/repo/playground.exs
asn1: 5.0.7, compiler: 7.2.7, connection: 1.0.4, crypto: 4.3.3, db_connection: 2.0.3, decimal: 1.6.0, ecto: 3.0.5, ecto_sql: 3.0.3, elixir: 1.7.4, hex: 0.18.2, inets: 7.0.2, kernel: 6.1.1, logger: 1.7.4, mix: 1.7.4, music_db: 0.1.0, poison: 3.1.0, postgrex: 0.14.1, public_key: 1.6.3, ssl: 9.0.3, stdlib: 3.6, telemetry: 0.2.0
06:12:45.383 [debug] QUERY OK source="albums" db=0.9ms decode=0.6ms queue=0.8ms
SELECT
count(1) FILTER (WHERE g1."name" = 'live'),
count(1) FILTER (WHERE g1."name" = 'jazz')
FROM "albums" AS a0
INNER JOIN "albums_genres" AS a2 ON a2."album_id" = a0."id"
INNER JOIN "genres" AS g1 ON a2."genre_id" = g1."id"
WHERE (a0."artist_id" = 1) []
[%{jazz: 2, live: 1}]
$