lcabrini
I hope this is the right place to ask this. I’m ultimately using Phoenix, but the question itself is Ecto-specific.
I have two tables: one holds languages (Ga, Twi, Fante, Ewe, Nzema, etc). The other one holds books which has a reference to the language it is written in, along with some other information. There is also a field called read, which is simply just the number of people who have read the book.
I want to be able to render a list of all the languages that have at least one book and for each of those languages show the 10 most read books. I got lazy and thought I could do something like the following:
book_query = from b in Book, join: l in Language, on: b.language_id == l.id, order_by: [desc: :read], limit: 10
Repo.all(from l in Language, preload: [books: ^book_query])
Of course, I should have understood that limit: 10 is going to apply across the book_query, not be applied per language, as I wanted. The problem is I’m a bit stumped as to how to solve this without resorting to running multiple queries, which I would like to avoid.
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 4- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
LostKobrakai
Lateral joins can do what you want to do in a single query. With lateral joins you can run a subquery per row of the parent.
lcabrini
Thanks. I heard about lateral joins, but never dug into it. I guess this is the time then.
lcabrini
So, after a toying around a bit with this, I came up with this:
This is almost there. I have verified that I get a maximum of 2 books per language. I could preload the languages to get the language name. However, I wanted books to be mapped to languages so that I can easily iterate over languages and then in an inner loop iterate over the books that “belong to” that language.
I’m sure that toying around with Elixir a bit I could figure out some way to arrange the data the way I need it. But if there is a clean way of having Ecto do that, I’d obviously prefer that.
lcabrini
I got it working. Just in case it would help somebody down the road, here is what I did:
I had simply left out the preload, that was all.