我正在尝试在我们的网站上设置自定义权限模块,并且相对较新,可以进行续集以及如何执行基本的嵌套急切加载操作。
我进行设置的方式是拥有三个模型:Permission
,PermissionDirectory
和User
。权限在列表中,嵌套在它们与目录的belongsTo
关系中。我在列表上有一个过滤器,可以根据用户是“允许”还是“拒绝”许可权进行过滤。用户与权限之间存在多对多关系,我要根据用户之间是否存在关联来确定是否“允许”了权限。
问题页面是在过滤特定用户的权限时。过滤用户是否被“允许”权限非常简单:
const directories = await models.PermissionDirectory.findAll({
limit,
offset,
where: { ["$permissions.users.id$"], userId },
include: [
{
model: models.Permission,
include: [{
model: models.User
}]
},
]
});
return directories;
但是事实证明,通过“拒绝”过滤是困难的。执行相反的条件将返回其他用户拥有的权限,而不是返回目标用户(由userId
参数指定)不具有的权限。
where: { ["$permissions.users.id$"], { [Op.ne]: userId }}
这不起作用。以我是否正在查询以获取User1的所有权限为“拒绝”的示例为例。如果User1具有Permission1,而User2也具有Permission1,则Permission1的目录将获得具有不是User1的用户的所有权限。由于User2与Permission1和User1.id != User2.id
关联,因此Permission1将包含在响应中。
但是,我可以通过首先查询具有userId的所有权限,列出其ID的列表,然后执行第二次查询以获取其ID不在该列表中的权限,来获得所需的效果。 。,但这需要两个呼叫,而不是一个。
Tl; dr我正在寻找一种方法来进行嵌套的,急切的加载查询,该查询的顶级权限目录将仅返回没有给定用户与之关联的目录/权限。
答案 0 :(得分:2)
经过大量的互联网搜查和许多死胡同之后,我想我知道这个问题的不幸答案:sequelize在构建复杂查询方面不是很好。
为了进一步澄清我的问题,mysql join types的概述将我的情况描述为Anti Semi Join。
为了在sequelize中实现此sql查询,我将需要能够执行一个子查询,该子查询似乎并没有被sequelize本机支持(由于问题#3961缺乏动静而导致)
在where语句中使用sequelize.literal
似乎可以满足我的需求,但是如果sequelize从一开始就将所有联接类型都集成到了它们的功能中,而不是仅使用内部联接和左联接,那将很好支持加入。对我来说似乎是一种疏忽。