Occurrent 0.8.0 is now available. It contains several important changes, must notably it introduces a better way to sort queries, by making use if the new org.occurrent.eventstore.api.SortBy API. Sorts can now be done on an arbitrary cloud event field, and they can also be composed:

var sortBy = SortBy.ascending(TIME, STREAM_VERSION);

Remember that for queries and sorts to be efficient over large data sets, you need a proper index!


  • Only log with “warn” when subscription is restarted due to “ChangeStreamHistoryLost”.
  • InMemoryEventStore now sorts queries by insertion order by default (before “time” was used)
  • Added a new default compound index to MongoDB event stores, { streamid : 1, streamversion : 1}. The reason for this is to get the events back in order when reading a stream from the event store and to make this efficient. Previous $natural order was used but this would skip the index, making reads slower if you have lots of data.
  • Removed the index, { streamid : 1, streamversion : -1 }, from all MongoDB EventStore’s. It’s no longer needed now that we have { streamid : 1, streamversion : 1}.
  • All MongoDB EventStore’s now loads the events for a stream by leveraging the new { streamid : 1, streamversion : 1} index.
  • CatchupSubscriptionModel now sorts by time and then by stream version to allow for a consistent read order (see MongoDB documentation). Note that the above is only true if you supply a TimeBasedSubscriptionPosition that is not equal to ``TimeBasedSubscriptionPosition.beginningOfTime()` (which is default if no filter is supplied).
  • Major change in how you can sort the result from queries. Before you only had four options, “natural” (ascending/descending) and “time” (ascending/descending), now you can specify any support CloudEvent field. This means that e.g. SortBy.TIME_ASC has been removed. It has been replaced with the SortBy API (org.occurrent.eventstore.api.SortBy), that allows you to do e.g.


    Sorting can now be composed, e.g.


    This has been implemented for all event stores.

  • It’s now possible to change how CatchupSubscriptionModel sorts events read from the event store during catch-up phase. For example:

    var subscriptionModel = ...
    var eventStore = ..
    var cfg = new CatchupSubscriptionModelConfig(100).catchupPhaseSortBy(SortBy.descending(TIME));
    var catchupSubscriptionModel = CatchupSubscriptionModel(subscriptionModel, eventStore, cfg);  

    By default, events are sorted by time and then stream version (if two or more events have the same time).