простенькое приложение для бронирования ивентов (по типу calendly). особенность базы в том, что там по-хорошему всегда нужно выбирать хороший partition key для хорошего распределения данных
решил выбрать дату события (в ISO без временной компоненты), чтобы создавалось по партиции на каждый день. но т.к. в ивенте принимает участие несколько юзеров, то запрос (чтение) ивентов становится слишком неоптимизированным (начинаются cross partitions query). в таком случае для юзеров логично иметь такую же запись, но с другим ключем партиции (в виде userId). тут на помощь приходит change feed от космоса, к-ый слушает инсерт ивента в контейнер, дальше создает копии ивента с трансформацией для каждого юзера и инсертит в другой контейнер. в итоге получается очень эффективное чтение и эффективная запись
вопрос вот в чем: допустим, юзер А хочет изменить ивент. для этого он посылает запрос на изменение в коллекцию для записи, к-ая партицируется по датам. и вот хочется по канонам рест-лайк вернуть модельку, к-ую мы проапдейтили. Но проблема в том, что форматы коллекций для записи и для чтения различаются. нормально ли реюзать маппер из чендж фида в операциях такого типа ?
или стоит уже пойти по пути полноценного CQRS (изначально вообще желания такого не было, как-то само пришло к этому), посылать команду и апдейтить интерфейс так же eventual через сокеты какие-то или пуллинг ?
интересен взгляд со стороны на подобные задачи (если представить, что они реальные и продуктовые)
Не очень понятно по какому принципу ты выбрал ключ, почему дата?
У тебя по сути должно быть: - коллекция ивентов с партишен ключём ивента - коллекция участников ивента с партишен ключём юзера + можно денормализацию деталей (дата + описание что бы календарь строить например) Причем гипотетически вторая коллекция нам нужна только для выборки "мои ивенты" и мы можем ее через чейндж фид и формировать, мол по выставке ивента или его изменения мы меняем записи в той проекции. За счёт этого "вся моделька в ивентах" как ты хочешь а выборки для других мы уже асинхронно обновляем. Поскольку это "для других" тот факт что обновление происходит синхронно не влияет на респонсы твоей апишки Если надо по дате агрегации какие делать - не уверен что это прям надо (не смог придумать) то можно третью коллекцию замутить, но источник правды (кто когда с кем и где) у нас будет всегда один в коллекции ивентов
Чтобы в рамках одной даты триггером бд проверить, что нет оверлаппинга дат для таких юзеров
Да, у меня всё так, за исключением партишн ключа первой коллекции (выше написал, почему) Но вот если мы денормализуем вьюшку для выборок, то при апдейте коллекции для записи что отдавать на фронт юзеру ? Идти по пути цкрс и делать команды, или больше по какому-то ресту и модельку для записи денормализовывать и выплевывать юзеру ? Кажется, что команды, асинхронные апдейты фронта и прочие шняги в такой простой апишке это оверкилл, поэтому хочется пойти по пути 2. И вот вопрос, норм ли это подход ?
@fes0r, есть мысли какие-то ? или лучше для таких штук космос дб просто не юзать ? :D
Я расписал же мысли
Я бы по участникам выборку бы делал а не по дате.
Ты читал доки хоть?) Или просто с наскоку хочешь
так тогда не проверить за оптимальный перф, что в такую дату нет ивентов
Можно делать составной ключ партиции. Можно делать индексы
а, точнее вообще не проверить, потому что тригеры / хранимки ограничены одной партицией. ну т.е. у меня идея какая: все ивенты для записи хранятся в контейнере events и партицированы по дате (для соблюдения правила "один юзер не может быть на двух и более встречах одновременно"), все ивенты для чтения хранятся в контейнере user-events, где партицированы по userId
тогда приходится искать по like / contains / startsWith + endsWith и на сете в 600к это оч сильно убивает перф
Ты можешь делать отдельные контейнера
Это не true invariant же
вай нот ? ну т.е. окей, тут у меня бизнеса нет, чтобы сказать тру / не тру, но в том же календли я не помню, чтобы на 1 - 1 ивенты мог кто-то другой подсоседиться )
Подсоединиться к макету или заскедулить ивент на то же время?)
Обсуждают сегодня