TargetAggregateIdentifier And Query

I’m new I Axon (Framework and server). I just have a question:
Let’s say we have this aggregate:

	...
	@AggregateIdentifier
	private Integer libraryId;

	private String name; 
	....

Querying this aggregate by sending the libraryId is staightforward.
But how can I query “by name”?
I’ve tried this, but I get no results (NPE).

PS: I found this answer. If we don t need the @TargetAggregateIdentifier , where to add it so?

You should not query the aggregate, you want to use a projection for your queries. This way you can optimize the aggregate for writes, and the projection for reads. Also, nu plotting the responsibility, both parts are a lot easier to maintain, then when they are combined.

For a projection you can use a relational database, MongoDB (using the mongo extension), or basically any database that supports your query demands best.

In case you need to coordinate the writes between aggregates, you need to use a saga/process manager.

OK. I think my question was not clear.
I do realise that we dont use query the aggregate, and rather use projections.
What I need to know is, how to use Axon SERVER (not MongoDB) to query a field in the in the payload. Just as like you would do in the traditional SQL.

Do you want to such in Axon Server UI to find all the events with a certain ‘name’, for debugging? Please explain the use case so we might help you better.

Hi @Bonzon, and welcome to the Axon community!

I’m not sure I fully understand your need, so I’ll make some assumptions. Correct me if/where I am wrong.

So you have an aggregate instances that you interact with via commands. Those publish events and update their state. IIUC, you’d like to check the state of an aggregate instance in Axon Server (like in a traditional DB). If that is indeed the case, it is not possible.

It is not possible because Axon Server is an Event Store, not an Aggregate Repository. Thus you can’t ask it to “find an aggregate with the name X”. What you could do instead is to ask it to "find the events containing X produced by given aggregate type". You can use the AxonServer UI to send a query written in Axon Server Query Language. In your case, it would be something like

payloadType = aggregateType and payloadData contains "Some Name"

Keep in mind that this will not give you the Aggregate instance’s current state nor all the events. Just those events that contain the desired name. The events before the name was set or after it was changed will not be there. So you may be unable to conclude what the state is, based solely on those events. If you want the actual state of the aggregate, you should create a projection that reacts to those events and updates aggregates’ states in some persistent storage (DB, Mongo, …)

I hope this helps. If that’s not what you need, please describe your case with an example.

Thanks for ur answers :slight_smile:
My hope was to only use the Axon server as an event store that also can give me the current state of the aggregate. By doing this, I won t be conserned to create another platform (DB, etc.) and deal with 2 phase commit etc.
This idea originates from this video. But maybe I was missing something.

You can use Axon Server as an Event Store. That’s what it is :wink: But there is a significant difference between an Event Store and State Store (RDBMS, NoSQL DB, etc.).

With an Event Store, you don’t save the state of the Aggregate. Only the events it produces. Then you reconstruct the Aggregate instance from those events when needed. Thus no current “state” of the Aggregate can be queried. You ONLY need an identifier to find the relevant events and construct an instance.

If you absolutely need to store state, you can go for State Stored Aggregates. In this case you don’t need an Event Store but an Aggregate Repository. That can be an RDBMS, NoSQL DB, etc. But this gives you less flexibility, and you are overwriting (and thus losing old) data.

Axon Framework can construct objects representing your Aggregate instances in both cases (from the events in the Event Store or the state in a configured Aggregate Repository). Either way, for any state-changing operation, all you need is to find the right instance that can make the change. To use an analogy, it makes no sense to say, “Someone called Milen, please respond to this message”. You’d want to say “@milendyankov, please respond to this message” instead.

For none state-changing operations (read-only), you’d want to build projections containing the data you can query. Those can be stored in DBs or files or in-memory or anything else. You can have many of those, each serving a different purpose in the most performant way for the given use case.

That, in essence, is what CQRS is about. Separating the write model from the read model. You are correct in pointing out that you can query the write model using a state-stored approach. But that is a side effect of the storage solution. it is not something your application should rely on. Unfortunately (or luckily :wink:) event stores do not offer that functionality.


Finally, let me tell you, I know how hard it is to make that mental switch. Especially for people who have been building DB-backed (and thus state-storing) applications for years. I was there myself once. But trust me, once you do, you’ll never look back :wink: I’ve been trying my best to explain those concepts in my talks:

I hope those will help you better understand the software development concepts Axon follows. But there is more:

Please, take some time to explore those. And if you need help, do not hesitate to drop another post here.

Thx for the detailed answer.
I guess I do have some home work to do.
PS: I m a consultant for a large company and I m trying to find out how to use CQRS in our new project by using Axon framework and Server.
If you are interested to know more about plz let me know.

Thx

Sure! I’d love to learn more. I’ll DM you to arrange something.