Sequelize 嵌套预加载查找嵌套关联不匹配的所有位置

Sequelize nested eager loading find all where nested association doesn't match

我正在尝试在我们的网站上设置自定义权限模块,我对 sequelize 以及如何执行基本的嵌套预先加载操作还比较陌生。

我的设置方式是我有三个模型:PermissionPermissionDirectoryUser。权限在一个列表中,嵌套在它们与目录的 belongsTo 关系中。我在列表上有一个过滤器,它根据用户是 "Allowed" 还是 "Denied" 权限进行过滤。用户与权限之间存在多对多关系,我通过它们之间是否存在关联来确定它们是否 "Allowed" 权限。

有问题的页面是在过滤特定用户的权限时。过滤用户是否"Allowed"权限就够简单了:

const directories = await models.PermissionDirectory.findAll({
  limit,
  offset,
  where: { ["$permissions.users.id$"], userId },
  include: [
    {
      model: models.Permission,
      include: [{
        model: models.User
      }]
    },
  ]
});

return directories;

但事实证明,按 "Denied" 过滤很困难。执行相反的条件将 return 其他用户拥有的权限,而不是 return 目标用户(用 userId 参数指定)没有的权限。

where: { ["$permissions.users.id$"], { [Op.ne]: userId }}

这行不通。以我查询获取 User1 的所有权限为例 "Denied"。如果 User1 具有 Permission1,而 User2 也具有 Permission1,则 Permission1 的目录将获得拥有非 User1 用户的所有权限。由于 User2 与 Permission1 关联并且 User1.id != User2.id,Permission1 将包含在响应中。

但是,我可以通过首先查询具有 userId 的所有权限,列出其 ID,然后执行第二个查询以获取 ID 不在该列表中的权限来获得所需的效果...但这需要两次调用而不是一次调用。

Tl;dr 我正在寻找一种方法来使用顶层的权限目录进行嵌套的预加载查询,该查询将 return 只有 directories/permissions 没有给定用户关联和他们在一起。

经过大量搜索互联网和许多死胡同后,我想我知道了这个问题的不幸答案:sequelize 不擅长构建复杂的查询。

为了进一步阐明我的问题,mysql join types depicts my scenario as an Anti Semi Join 的大纲。

为了在 sequelize 中实现这个 sql 查询,我需要能够执行一个子查询,它似乎不受 sequelize 本身的支持(从问题上缺乏运动来衡量#3961).

在 where 语句中使用 sequelize.literal 似乎可以很好地满足我的需要,但如果 sequelize 从一开始就将所有连接类型合并到它们的功能中,而不是只有内部连接,那就太好了并支持左连接。对我来说似乎有点疏忽。