Ecto.Query.API.map
map
, go back to Ecto.Query.API module for more information.
Used in select
to specify which fields should be returned as a map.
For example, if you don't need all fields to be returned or
neither need a struct, you can use map/2
to achieve both:
from p in Post,
select: map(p, [:title, :body])
map/2
can also be used to dynamically select fields:
fields = [:title, :body]
from p in Post, select: map(p, ^fields)
If the same source is selected multiple times with a map
,
the fields are merged in order to avoid fetching multiple copies
from the database. In other words, the expression below:
from(city in City, preload: :country,
select: {map(city, [:country_id]), map(city, [:name])})
is expanded to:
from(city in City, preload: :country,
select: {map(city, [:country_id, :name]), map(city, [:country_id, :name])})
For preloads, the selected fields may be specified from the parent:
from(city in City, preload: :country,
select: map(city, [:country_id, :name, country: [:id, :population]]))
It's also possible to select a struct from one source but only a subset of fields from one of its associations:
from(city in City, preload: :country,
select: %{city | country: map(country: [:id, :population])})
IMPORTANT: When filtering fields for associations, you MUST include the foreign keys used in the relationship, otherwise Ecto will be unable to find associated records.