Нужно правильно организовать связь user-role roles: Set<DBRef> (у меня в коде

Set<RoleDocument>)
roles: Set<ObjectId>
roles: Set<RoleDocument>

1) C первым все ок. Мой драйвер успешно тащил при findAll все что нужно + я слыхал там даже lazy есть теперь у DBref

Но мне понадобилось (задача Х) отфильтровать findAll users по rights, которые в роли.
Как я понял с DBRef это не сделать (по крайней мере малой кровью).

2) С Set<ObjectId> (manual reference) я наколбасил такую штуку
db.ucars_user.aggregate([{ "$lookup": { "from": "role", "localField": "rolez", "foreignField": "_id", "as": "rolezz" } }, {"$project": {"rolezz": 1}},{ "$match": {"rolezz": { "$elemMatch": { "name": { "$eq": "role3"}}}}}])

И она делает то что мне надо - (задача Х) (ну в запросе названия role rolezz в зав-ти от названий коллекций и поля у юзера)

И это работает. Но при findAll users мне придется как-то доставать для каждого юзера роли (с Set<ObjectId> ходить за реальными ролями). Это тоже аггрегацией решается наверно. То есть мне придется пистаь кастомный запрос findAll, а до этого все из коробочки делалось springData (ну тоже с lookup)

Не хочется писать слишком мнго кастомных запросов
3) И что я решил сделать, не знаю верно ли это
Сделать в users целый Set<RoleDocument> То есть хранить и айдишник и Set<String> (rights)
Но при этом все равно иметь отдельную коллекцию RoleDocument (для своих целей)

Минус в том, что при edit RoleDocument элементов придется проходиться по коллекции users (allusers) и там менять RoleDocument чтобы они соответствовали тем, что в коллекции RoleDocument.
То есть если было
UserDoc:
id: 1
roles: { Role1: {right1,right2} }
RoleDoc:
id: 1
rights: {right1, right2}

И мы решили сделать
RoleDoc:
id: 1
rights: {right1}

Придется пройтись по всем юзерам и вручную у них roles: { Role1: {right1,right2} } >>> roles: { Role1: {right1} }

И при вставке нового юзера проверять что rights: Set<String> с id=Y тоже соответствует Set<String> в коллекции RoleDocument с id=Y.

Таким образом мне не придется имплементить заного findAll/find итд для юзера, чтобы он $lookup зависимость...
Так как updateRole операция редкая, а при вставке юзера проверить соответствие не оч трудно, вроде норм? или лажа все равно и надо брать пункт 2 с lookup на каждый чих?))))

1 ответов

2 просмотра

Когда я приступал к реализации ролевого контроля доступа, то тоже поначалу хотел хранить роль просто в документе пользователя. Но я крайне не рекомендую подобный подход, потому что в дальнейшем он череват большой головной болью. Просто подумайте, что придется сделать, если роли будут изменяться, удаляться, добавляться. Сменилось название роли - надо пробежаться по всем и у всех поменять. Добавился новый permission в роль - добавить у всех. Решили добавить новое поле в документ роли (к примеру, помимо названия роли может быть её написание на русском, к примеру admin - Администратор, также можеть быть описание роли, и.т.д.) - опять же обновлять у всех. С удалением точно также. Принцип простой - разные коллекции для разных сущностей. Насколько я знаю, aggregation framework хорошо работает с подобными запросами. Вы ведь вполне можете протестировать производительность запросов по заданным условиям - вставте сколько необходимо документов пользователей с ролями в базу, и погоняйте запросы, замеряя время их выполнения. Я уверен, что если все сделать правильно, система будет работать хорошо и быстро.

Похожие вопросы

Обсуждают сегодня

Всем привет. Подскажите, почему не меняется значение поля при переключении сайта?
Alexander Peterikov
11
Можно ли загрузить скрипт py в бота чтобы он работал по нему? как это сделать?
huskadam #RCC Фанат? @hitlerpvp
13
Добрый день! Кто-нибудь знает как подключить твиг в контроллеры плагина?
Николай Афанасенко
5
@dblackCat Привет. Это же твой плагин? https://octobercms.com/plugin/catdesign-productbundle
Alexey Yakimov
5
'frakturBold' => ['𝖆', '𝖇', '𝖈', '𝖉', '𝖊', '𝖋', '𝖌', '𝖍', '𝖎', '𝖏', '𝖐', '𝖑', '𝖒', '𝖓', '𝖔', '𝖕', '𝖖', '𝖗', '𝖘', '𝖙', '𝖚', '𝖛', '𝖜', '𝖝', '𝖞', '𝖟', '𝕬', '𝕭', '𝕮', '𝕯'...
Roma
4
привет, а расскажите как бэкапите свой vault raft cluster CE? я немного почитал и понял, что нужно как-то выполнять vault operator raft snapshot save backup.snapshot подсовыва...
[DBST] Dmitry Knyazev
5
Добрый день, не подскажите, если в OC-V3 поменять страндартную директорию /storage/ на /storage2/ - не будет сильно много проблем ?
Max Dubovsky
32
Ребят, а за скок можно впарить анон чат с апишкой и веб админкой ?
Eugene Неелов
15
Ты просто гитлеровскую эстетику плохо понимаешь. Он же всё под Цезаря делал. А это как бы запрещённый приём в политике. Пиджаки они зачем все носят? Чтобы показать что они тип...
Ivan Kropotkin
4
Всем привет! Напишите пожалуйста, кто мог бы оффлайн преподавать некоторые курсы по Odoo в Алматы в одном из ВУЗов? Мы сейчас вместе с Odoo запускаем университетскую программу...
Adil Dauletkhan
2
Карта сайта