对嵌套的渴望加载进行排序,查找所有嵌套关联不匹配的地方

时间:2018-07-05 23:33:36

标签: sql sequelize.js graphql graphql-js

我正在尝试在我们的网站上设置自定义权限模块,并且相对较新,可以进行续集以及如何执行基本的嵌套急切加载操作。

我进行设置的方式是拥有三个模型:PermissionPermissionDirectoryUser。权限在列表中,嵌套在它们与目录的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我正在寻找一种方法来进行嵌套的,急切的加载查询,该查询的顶级权限目录将仅返回没有给定用户与之关联的目录/权限。

1 个答案:

答案 0 :(得分:2)

经过大量的互联网搜查和许多死胡同之后,我想我知道这个问题的不幸答案:sequelize在构建复杂查询方面不是很好。

为了进一步澄清我的问题,mysql join types的概述将我的情况描述为Anti Semi Join

为了在sequelize中实现此sql查询,我将需要能够执行一个子查询,该子查询似乎并没有被sequelize本机支持(由于问题#3961缺乏动静而导致)

在where语句中使用sequelize.literal似乎可以满足我的需求,但是如果sequelize从一开始就将所有联接类型都集成到了它们的功能中,而不是仅使用内部联接和左联接,那将很好支持加入。对我来说似乎是一种疏忽。