artem

artem

How you would do a cross-aggregate projection with Commanded?

Hi all

I am new to Commanded and whole world of CQRS, trying to evaluate whether it would suite my case. I would appreciate suggestions on how you would do a cross-aggregate projection.

I am thinking about a small specialized Human Resources related service. Candidates submit their resumes, Recruiters submit their vacancies. Commanded and CQRS should work just fine for whichever slices and dices I’d want to have e.g. for listing the highest paying vacancies in a particular field.

But I can’t wrap my head about recommendations. If I have a primitive recommendation engine to recommend candidates with elixir skill to recruiters looking for elixir skill and the other way around, does it essentially mean that I need to build a projection (a PostgreSQL table most probably) on every vacancy/candidate update? Possibly even rebuild the whole table on every small aggregate change?

  • Is it normal and expected or am I missing something?
  • Or is it conceptually okay to have separate projections for candidates/recruiters and “derive” recommendations by querying them with an sql JOIN? Even if recommendations will become more computationally intensive later (e.g. require calling a machine leaning mode)?
  • Or is it a known problem with the known recommendations?
  • How would you do it? I will be grateful for any pointers.

Most Liked

tcoopman

tcoopman

Hi Artem,

I think there are multiple solutions to what you’re talking about and they are not as much commanded related, but are practices related to EventSourcing in general.

Most of this depends on how you’re modelling your solution.

Firstly, a side remark that might be not super relevant for your question, but I’d like to add it anyway:
In Domain-Driven Design (DDD) I like to make it very explicit what an aggregate is: An aggregate is responsible to keep certain constraints consistent at all times.
On the other hand in EventSourcing a stream is some logical grouping of events. For example everything that happens on 1 resume, could be a stream, but I would only call it an aggregate when you also have constraints that you need to guard.

So coming back to your question, it now depends on how you model everything.
Is a person a stream? a resume? looking for candidates?

Depending on how you model that, your need for projections will also change.
For example, I guess this would be your default model:


(green is the query, orange events)

But you could also use a process manager:

In this case, we have a process manager that links skills and vacancies, so that our projection is a bit simpler.

But we still have a total free choice on what the projection writes. it can be 1 table, multiple tables, it can be multiple projections.
If you want advice on that, I propose that you work out your question in a bit more detail. How do recommendations look like? What information do they need to contain. Why would you have to rebuild the whole table on every change?

Where Next?

Popular in Questions Top

gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
Werner
Hi, I’m using Ubuntu 18.04 and after updating to OTP-24.0 yesterday i have this warning when I run “mix local.hex”: 14:57:30.512 [warn] ...
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
Kagamiiiii
Student & New to elixir. Nice language. I want to convert a english character, e.g. “a”, which is stored in a variable, to it’s asci...
New
dokuzbir
Hello, I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these buyer = %{ id: ...
New
sacepums
Hey guys. I'm new to elixir and im really stocked about it. But I ran into a bit of problem - I need to convert a date sting, for examp...
New
Phillipp
Hey, I have a NanoPi-M3 and try to install Elixir on their Ubuntu image. I followed the Raspberry Pi installation instructions from the ...
New
makeitrein
Hey all, just started picking up Elixir last week and am writing a scraper as a learning project. Baby step #1 is extracting the number ...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New

Other popular topics Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
sergio
I couldn’t find any guides that worked well with Phoenix 1.6.0 and esbuild. I hope this helps people test the waters and eases you into t...
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New

We're in Beta

About us Mission Statement