Отчетность в мире CQRS/ES

Я думаю, что понимаю идею модели чтения в контексте ES + CQRS (пожалуйста, поправьте меня, если не так). Однако у меня все еще есть некоторые сомнения относительно его использования в контексте «серьезных» репортажей. Допустим, я использую реляционную базу данных плюс немного ORM для проверки моих моделей чтения. Одна базовая «модель чтения сводной статистики» может выглядеть так:

 class SummaryStats1
    {
    public Guid TypeId { get; set; }
    public string TypeName { get; set; }
    public Guid SubTypeId { get; set; }
    public string SubTypeName { get; set; }
    public int Count { get; set; }
    }

Учитывая событие:

TypeId = 3acf7d6f-4565-4672-985d-a748b7706a3e
TypeName = Bla1
SubTypeId = 41532aa1-f5d1-4ec4-896b-807ad66f75fc
SubTypeName = Bla2

Нормализатор будет:

(1) Проверьте, существует ли экземпляр вышеуказанной комбинации (определяется TypeId, TypeName, SubTypeId, SubTypeName) (2) Если экземпляра нет, он создаст экземпляр и установит Count равным единице. Если есть, это увеличит количество на единицу.

Является ли это приемлемым подходом к отчетности? Я предполагаю, что можно использовать очень эффективные выборки для этой денормализованной структуры данных (для фильтрации и других «проекций» sql):

SELECT  TypeName, Sum(Count) FROM SummaryStats1 GROUP BY TypeName

Согласятся ли с этим эксперты CQRS/ES? Является ли это «способом» ведения дел (т. Е. Создавать эти специальные модели чтения отчетов)? Буду очень признателен за любые ссылки на исходный код/реальные примеры.


person cs0815    schedule 03.06.2014    source источник


Ответы (1)


Является ли это приемлемым подходом к отчетности?

Будь то отчетный подход, конечно, зависит от ваших требований, но общая идея верна.

В итоге:

Вы создаете свои модели чтения (иногда используется официальный термин EagerReadDerivation) на основе предстоящих событий. с вашего домена.

Модели чтения могут быть любыми (sql, redis, mongo и т. д.). Независимо от того, что позволяет вашим запросам быть эффективными. В вашем примере, например, нет причин, по которым вы не можете иметь 2 модели чтения, чтобы еще более эффективно выполнять ваши запросы (хотя то, что вы описываете, вероятно, достаточно для большинства случаев):

  1. ваш вид sql, как описано
  2. предварительно агрегированное представление, сгруппированное по typeName, чтобы вам не приходилось делать группу каждый раз во время запроса (вместо этого вы вычисляете группировку в нормализаторе).

Короче говоря, нет правильного или неправильного способа построения моделей чтения. Прелесть именно в том, что вы совершенно свободны моделировать свои модели чтения любым способом (на основе шаблона запроса и узких мест производительности, которые вы себе представляете), не задумываясь о том, как эти модели влияют на запись (просто потому, что они не влияют, поскольку cqrs разделяет чтение и запись)

Использование событий в сочетании с CQRS дает еще более приятные возможности, а именно создание новых моделей чтения и заполнение их данными, просто воспроизводя прошлые события из источника событий.

Вот несколько дополнительных примеров того, что можно считать «моделью чтения» ваших данных:

  • представление INCR с Redis (что является альтернативой тому, что вы описали)
  • Индекс поиска Elasticsearch/Solr
  • KV-хранилище/индекс для быстрого поиска по ключу.

Опять же, идея заключается в том, что эти «модели чтения»/представления всегда обновляются (в конечном итоге согласуются), отправляя им события обновления (обычно с помощью pubsub)

Для более подробного чтения см. Ответ плюс ссылки на этот вопрос: Реализация на стороне чтения подходы с использованием CQRS

person Geert-Jan    schedule 03.06.2014
comment
Спасибо, Герт-Ян, ваш ответ вселяет в меня некоторую уверенность в том, что, как мне кажется, я понимаю (-: вы упомянули «2 модели чтения» для моего сценария. Что это значит? Они объединены для достижения вышеуказанного? чего следует избегать ... ? - person cs0815; 03.06.2014
comment
Это означает, что вы представляете одну и ту же информацию двумя способами, каждый из которых лучше подходит для конкретного сценария. Одна модель чтения не знает о другой. Служба запросов (или что у вас есть) будет использовать любую из этих моделей для извлечения данных, но не обе из них (это не правило, но нет смысла использовать их обе сразу) - person MikeSW; 03.06.2014
comment
Действительно, как сказал @MikeSW - person Geert-Jan; 04.06.2014