How to write an Ecto query to generate a dynamic select statement--variable number of fields selected?

Hello Elixir Community:

I need to return a variable number of fields (database columns) using an Ecto query. I found in the Ecto 3.2 (version I’m using) documentation the ability to do this:

from(City, select: [:name])

which is supposed to limit the returned fields to that list of atoms corresponding to the field names according to the docs, but I’m getting the entire schema-defined struct. I do get only specified fields returned when using key/val structures (keyword list or map) as the value of select: but not with a list of atoms which is what I need. Any ideas how to make this work? Thanks!

That does indeed only return the :name field, but structs need everything defined, so it defines only name but the rest get default constructed.

If you want it in another format then you can do something like select: %{name: c.name} or use the map or fields function to dynamically build one (see the Ecto.Query.API module docs), or you can return a tuple, or a list, or a variety of other things (see the Ecto.Query.select function docs). :slight_smile:

1 Like

Oh! Now I understand. It makes sense that all the other fields were set to nil when using my original attempted solution. As you said the map/2 function can solve this:

From Ecto.Query.API

from p in Post,
select: map(p, [:title, :body])

2 Likes

Yep, I like the map function, I use it quite a lot. ^.^;

1 Like