Aggregates with resource relationships
Hello!
So maybe there's something I'm not quite understanding from the documentation, but say I have a State and City. A state can have many cities, so:
And a city belongs to a state:
Now for a state, say I want an aggregate for the number of cities in the state. Do I have an
aggregates
block like the following?
Also, could this be a oneliner as just count :number_of_cities, :cities
? No do ... end
?
Thanks!15 Replies
Yes, this should do what you want:
The do block is an alternative syntax that is sometimes required for passing more complicated options.
filterable?
is true by default.Okay, I didn't quite know if when it said
The relationship or relationship path to use for the aggregateThat would also include fields for actual relationships between resources.
In the case of count, you generally don't need to refer to a specific field. But in the case of say a
first
or sum
aggregate, you often want a specific field.
For example, sum :total_population, :cities, :population
So for list, if the default field is the primary ID
The field to aggregate. Defaults to the first field in the primary key of the resource
The path can also traverse multiple relationships deep, which is very convenient.
Do I need to just have
list :cities_in_state, :cities, :id
?I've actully never used the list aggregate, so I'm not familair w/ the API on that one. 😅
Looking at the docs, it looks like the 3rd argument is the field, yes.
list [name], [relationship], [field]
Well I'll try that and see if works. How exactly do aggregates get created and stored? So a state could have like 20000 cities, so if I call for that aggregate somewhere with Ash am I going to have to wait for that aggregate to be initialized the first time?
I guess that's more of a question about Postgres than Ash...
Sorry, missed your last question. It will return whichever field (id by default). So if you wanted a different field (like
:label
), you'd just need to specify it.Oh okay. Well it says that
field
is required but it defaults to the primary ID so I was confused as to whether or not it's actually required.Yeah, that is more of a PG specific question, and I'd assume for something that large, you would want an index to increase efficiency.
You can omit it if
:id
is OK.Well looks like I found what I might need. https://ash-hq.org/docs/dsl/ash-resource#postgres-custom_indexes
Also I guess there's always the solution of creating materialized views with SQL in the migrations.
Yeah, I'm using a materialzed view for a report or two and have an Oban job that refreshes it regularly and on demand.
Oh shoot. I forgot about the Oban library. That could fit our use cases pretty well if we don't feel like having cron jobs that run
mix
.