dli
Preload multiple associations with only one join?
I have two schemata Person and Book.
Both Book.author_id and Book.illustrator_id reference Person.id.
I want to load all books and preload all associated people. My query looks like this:
from(b in Book,
join: a in assoc(b, :author),
join: i in assoc(b, :illustrator),
preload: [author: a, illustrator: i]
)
|> Repo.all()
I have a very large number of books. Would it be possible to join Person only once and let an Ecto preload function handle the matching?
Strangely enough, the following code correctly preloads the author, but illustrator is always identical to author which is wrong.
join: p in Person,
on: p.id in [b.author_id, b.illustrator_id],
preload: [author: p, illustrator: p] # ???
Most Liked
LostKobrakai
SQL will always return tabular data, no matter how hard one tries to think of it as nested or treelike.
So given a row with book details you add columns for person data using a join. But you only get enough columns for a single joined person. If you want to join another person you need to do another join, which will one more set of columns to the resulting data.
That’s why your preload doesn’t work as you expect. You’re joining either an author or an illustator and then telling ecto to use that single set of data for both relations.
LostKobrakai
While this is generally true I doubt there’s many cases if at all where joining distinct data as separate rows over joining as separate columns will yield a performance boost. That’s something I’d only start touching as one of the later options once a query in question was proven to be a hotspot. Foreign keys on primary keys of other tables are hella fast, because the primary key is the the primary way to look up information on that table. It’s afaik always indexed and basically the first thing any db engine will make sure is fast.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








