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