У меня есть объект Person в системе. Когда человек выполняет какое-либо действие, появляется актер-администратор, который заинтересован в наблюдении за такого рода событиями.
Person
{
Id: string
}
PersonAction
{
ActionType: enum
PersonId: string
}
В настоящее время эта подписка реализована посредством ServiceBus topi c и подписок: администраторы подписываются на действия все люди в системе:
- Azure Сервисный автобус имеет брокера
PersonActions
topi c. - Каждый раз, когда Person выполняет какое-либо действие, в Topi c.
- отправляется событие
PersonAction
. Каждый администратор создает собственную подписку на topi c и отслеживает все действия Persons. .
Теперь у меня есть новое требование, которое вводит группирование лиц, и мне нужен способ, позволяющий администраторам подписываться на события PersonActions на основе групп, которые они хотят отслеживать:
- Люди могут быть частью одной или нескольких групп.
- Администраторы заинтересованы в мониторинге групп лиц и, следовательно, получении всех событий PersonAction для групп, которые они отслеживают.
- Администраторы могут подписаться на одну или несколько групп.
Вот мои мысли о том, как это сделать:
- Добавить в PersonAction свойство маршрутизации, которое будет содержать информацию о группах, членом которых этот человек является
- Когда администратор создает новую подписку, он будет указать набор групп, которые он хочет отслеживать, и он должен быть как-то использован в фильтре подписки для фильтрации сообщений PersonAction в Topi c.
Итак, сокращая дело, я хочу использовать возможности фильтрации Service Bus Topi c для доставки сообщений PersonAction специально для администраторов, которые заинтересованы в них, на основе групп.
В общем, это не кажется простой задачей для ServiceBus (или любой другой). другой брокер сообщений) потому что есть отношение многие ко многим on: один человек может входить в несколько групп, и администратор может захотеть подписаться на несколько групп. Обычно все фильтры поддерживают фильтрацию, когда событие имеет единственное свойство (например, «groupId = 1234»), и в моем случае это массив.
Пока что я придумал два решения, но мне не очень понравилось любой из них:
Используйте LIKE SqlFilter. Объедините все группы Person в одну строку, разделенную запятыми (groups=1,2,5,8
), и затем установите фильтр groups LIKE %1% OR groups LIKE %5%
(в действительности идентификаторы групп будут путеводителями, поэтому не берите в голову проблему с одним идентификатором группы, являющимся подстрокой другого )
Добавьте каждый идентификатор группы в качестве свойства с пустым значением, а затем используйте фильтр EXISTS, чтобы проверить, определено ли в событии этот идентификатор группы. Фильтр будет иметь свойства EXISTS(1) OR EXISTS(5)
и PersonAction: {1:null, 2:null, 5:null, 8:null}
Есть ли лучший способ выполнить такую фильтрацию и как выполняется правило фильтрации «многие ко многим» в брокерах сообщений?
Ответы, описывающие это для любого брокера сообщений (не только ServiceBus), также будут чрезвычайно полезны.