с ней skip limit в агрегейшн)
Структура такая (лишнее не писал):
User:
_id
Set<Role> (Set<ObjectId> - мануал референс)
Set<Right>
Role:
_id
Set<Right>
То есть у юзера есть права, плюс список ролей, у каждой роли еще список прав (то есть права можно добавлять с ролями, а можно и без ролей)
Нужно отфильтровать по списку прав findAll(Set<Right> filterList)
Сначала сделал проджекшн из проджекшна, потом подумал что плодить $project в aggregation это плохо.
(Промежуточный вопрос: Если в агрегейшне есть 2 прожекшна - это плохо? Они как-то грузят запрос, память итд? Думаю да)
Свел к этому:
db.collection.aggregate([{"$lookup":{"from":"role","localField":"roles","foreignField":"_id","as":"rls"}},{"$addFields": { finalRoles: { $setUnion: [ { $reduce: { input: "$rls.rights", initialValue: [ ], in:{$concatArrays: ["$$value","$$this"]}} },"$right"]} }}, {"$match": { "finalRoles": {"$in": ["ADMIN","asdf"]}}}])
Лукапом достал по айдишникам, потом добавил поле куда смержил права от ролей, редьюсом собранные в кучу, и юнион с rights которые в юзере отдельно от ролей ну и в конце match
Вроде работает.
Но вопрос в том (по сути вопрос ничем не отличается от предыдущего промежуточного), плохо ли, что я сделал addField, только чтобы там что-то искать? Может можно сделать этот поиск match по этой выборке не делая addField?
Да и вообще может это совсем не так надо было сделать
Плюс я посмотрел - в моем апи нет addField , но в интернетах предлагают такой воркераунд)))
$project: {
custom_field: "$obj.obj_field1",
document: "$$ROOT"
}
а задача какая? что вы выбираете?
Обсуждают сегодня