"State of a Kingdom" projection

222 views
Skip to first unread message

Alexey Raga

unread,
Feb 20, 2013, 4:32:52 AM2/20/13
to ddd...@googlegroups.com
Hi Guys,

There is a Kingdom where a number of feudal lords and peasants live.

Peasants are getting assigned to feudal lords and may be reassigned from time to time. Say, a peasant receives a formal letter which states that from now on he belongs to another lord and which he must obey.

Feudal lords don't know their peasants by name and they don't really care.

Now the King wants to see the helicopter (or an air balloon to that matter) view of his kingdom. He wants to know which feudal lords has how many peasants.

Assuming that we have two aggregates: FeudalLord and Peasant and some events like:
PeasantAssignedToLord {peasantId, lordId}
PeasantUnassignedFromLord {peasantId, lordId}
PeasantDied {peasantId} //yes, it is a life and people die :( Note that there is no lordId in this event.

How we can build this projection efficiently to satisfy his majesty curiosity?

Cheers,
Alexey.

@yreynhout

unread,
Feb 20, 2013, 5:54:19 AM2/20/13
to ddd...@googlegroups.com
<5 second solution/>

Projection structure
{
"FeudalLordId" : "<lordId>"|null
"PeasantId" : "<peasantId>"
"PeasantState" : "<assigned|unassigned|dead>"
}

Pseudo query

Select FeudalLordId, Count(PeasantId)
From Projection
Where PeasantState == 'assigned')
Group By FeudalLordId

Dennis Traub

unread,
Feb 20, 2013, 6:20:04 AM2/20/13
to ddd...@googlegroups.com
Why two steps in the re-assignment (unassign from one, assign to the other)? Will a peasant ever be free? I modified Yves' example a bit.

Peasant: {
    PeasantId : <peasantId>,
    ServesLordId : <lordId>,
    StillAlive : <true|false>
}

Events:
PeasantDied { peasantId }
PeasantSubjugated { peasantId, lordId }

SELECT ServesLordId, Count(PeasantId)
WHERE StillAlive
GROUP BY ServesLordId



--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Alexey Raga

unread,
Feb 20, 2013, 8:47:21 AM2/20/13
to ddd...@googlegroups.com
Yes, that's what I would be thinking too if I was using SQL database for projections.
The thing is that now I am using files (works well) and am looking forward to use the Event Store in the future.

Loading all these linking pairs in memory every time the dashboard needs to be updated may be expensive so I was looking for a way to have it pre-built :)

Saying that, I understand that these structures would only take a couple of megabytes for 50 000 records, so maybe you can say that it is a premature optimization, but I am just exploring the options :)

Alexey Raga

unread,
Feb 20, 2013, 8:51:06 AM2/20/13
to ddd...@googlegroups.com
>>Why two steps in the re-assignment
Oh, absolutely :) There was no reason and it was not the point. It was just for explaining the domain :)
BTW, sometimes it is nice to have an explicit event if there is something in business triggered by the fact that a peasant is unassigned.

James Bradt

unread,
Feb 20, 2013, 9:10:50 AM2/20/13
to ddd...@googlegroups.com
Maybe I'm missing something...

Why not create a second projection that is the cached representation of the information for that dashboard?


Kijana Woodard

unread,
Feb 20, 2013, 10:04:39 AM2/20/13
to ddd...@googlegroups.com

I wouldn't say the peasant is free. I would say that the unassignment as been recorded and the assignment has not yet been recorded.

I'm sure similar circumstances happen in non computing systems all the time. Yes, if the emperor asked each lord for a spot count, there could be 'missing peasants', but for each lord, the totals would balance perfectly.

On Feb 20, 2013 8:10 AM, "James Bradt" <james...@gmail.com> wrote:
Maybe I'm missing something...

Why not create a second projection that is the cached representation of the information for that dashboard?


Bruce Onder

unread,
Feb 20, 2013, 10:55:11 AM2/20/13
to ddd...@googlegroups.com
Why two steps in the re-assignment (unassign from one, assign to the other)? Will a peasant ever be free? I modified Yves' example a bit.

//Projection
Fealty: {
LordId : <lordId>,
PeasantCount : 0
}

Events:
PeasantDied { peasantId, lordId } - decrements counter for lord

PeasantSubjugated { peasantId, fromlordId, tolordid } decrements from lord, increments to lord

SELECT LordId, PeasantCount From Fealty

Why are Peasants ARs and not Value Objects? Why do they need identities in the kingdom other than to kill them?


Alexey Raga

unread,
Feb 21, 2013, 3:22:42 AM2/21/13
to ddd...@googlegroups.com
No, you are not missing anything :)

I am doing exactly this right now: building projection files that links lords and peasants together and having a "task" that periodically builds another projection based on the first one.

I am just trying to confirm if there is more efficient way of doing it (because I can't see it myself).

Cheers,
Alexey.

James Bradt

unread,
Feb 21, 2013, 9:55:29 AM2/21/13
to ddd...@googlegroups.com
"it depends"?

how about: instead of having a secondary task that periodically builds one projection from another, why not dispatch the event stream for each projection simultaneously? 

Vladik Khononov

unread,
Apr 3, 2014, 12:00:57 PM4/3/14
to ddd...@googlegroups.com
I think there is a missing piece in the question. To discover it, lets ask two questions:
* Does the lord has anything to do with a dead peasant?
* Should a dead peasant be assigned to his lord for good?

The answer to both questions probably is "no", therefore, a PeasantDied event should trigger a saga that will take care of the dead peasant - maybe arrange a funeral for him and unassign the peasant from his lord by raising the PeasantUnassignedFromLord event. Maybe even specifying a reason - "death".
Now you can build the projection in a simple file without any extra loops.

Kijana Woodard

unread,
Apr 3, 2014, 7:20:04 PM4/3/14
to ddd...@googlegroups.com
Talk about dead peasants.
Thread Resurrection!


--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages