CQRS (источник событий): прогнозы с несколькими агрегатами - PullRequest
0 голосов
/ 09 декабря 2018

У меня есть вопрос относительно проекций, включающих несколько агрегатов в архитектуре CQRS.

Например, предположим, у меня есть два агрегата WorkItem и Developer, и что следующие события происходят последовательно (но не сразу)

  1. WorkItemCreated (workItemId)
  2. WorkItemTitleChanged (workItemId, title)
  3. DeveloperCreated (developerId)
  4. DeveloperNameChanged (developerId, имя)
  5. WorkItemAssigned (workitemId, DeveloperId)

Я хочу создать проекцию, которая будет являться «внутренним соединением» для developer-workitem:

| WorkItemId | DeveloperId | Title  | DeveloperName | ... |
|------------|-------------|--------|---------------|-----|
| 1          | 1           | FixBug | John Doe      | ... |

То, как яделать мои прогнозы постепенно.Это означает, что я загружаю сохраненные прогнозы из базы данных и применяю оставшиеся события по мере их поступления.

Моя проблема в том, что событие, ответственное за создание строки в таблице проекций, - WorkItemAssigned.Однако это событие не содержит необходимой информации из предыдущих событий (название рабочего места, имя разработчика и т. Д.)

Чтобы получить требуемую информацию ко времени WorkItemAssigned, мне нужно загрузить все событий из хранилища событий, сохраняйте состояний в памяти для всех WorkItems и Developers, поэтому у меня есть необходимая информация к моменту прибытия события WorkItemAssigned.

Конечно, я мог бы получить прогноз для Workitem, другой для Developer и запросить их, чтобы получить их последние состояния.Но, похоже, много работы, если я хочу создать прогнозы для каждого агрегата отдельно, я мог бы также создать представление базы данных для inner-join их (На самом деле, это то, что я делаю.)

Я не делаю все это вручную, в настоящее время я использую хороший фреймворк под названием EventFlow , но он не заставляет меня отвечать на этот вопрос.

Это вопрос об основах CQRS, и я упал, я что-то здесь упускаю.

1 Ответ

0 голосов
/ 11 декабря 2018

Я не думаю, что вы ничего не упустили.Проектирование моделей чтения в системе, основанной на событиях, представляет собой другой набор проблем, нежели запросы из реляционной модели.Проблемы не обязательно легче или труднее решить;они просто разные .

Хорошая новость в том, что у вас есть много вариантов.Event Sourcing позволяет проецировать данные любым мыслимым способом, поэтому вы можете выбрать решение, наиболее подходящее для каждой отдельной проекции.Я предполагаю, что «плохие» новости (я бы сказал, что это не плохие новости) заключаются в том, что решение проблемы не всегда одинаково, как с реляционной системой, которая состоит в создании запроса с использованием JOIN.

Вы уже определили несколько возможных решений:

  • Используйте реляционную модель в качестве одной из ваших моделей чтения
  • Когда наступает событие определенного типа, повторите запроспотоки, которые содержат необходимые данные и используют их для проецирования по требованию

Вы также можете просто хранить некоторые данные в промежуточном состоянии (в памяти, базе данных документов, файловой системе и т. д.), которыепозволяет вам искать данные и проецировать их при необходимости.Поэтому сохраняйте списки обновленных WorkItems и разработчиков, где их можно читать и использовать всякий раз, когда наступает событие WorkItemAssigned.

Я бы сказал, что создание реляционной базы данных в качестве модели временного или постоянного чтения - это вполне жизнеспособный способ решения проблемы.проблема, если вы не пытаетесь добиться масштабируемости.

...