Sequelize嵌套的渴望加载找到所有嵌套关联不匹配的地方
Posted
技术标签:
【中文标题】Sequelize嵌套的渴望加载找到所有嵌套关联不匹配的地方【英文标题】:Sequelize nested eager loading find all where nested association doesn't match 【发布时间】:2018-12-14 12:28:53 【问题描述】:我正在尝试在我们的网站上设置自定义权限模块,并且对续集以及如何执行基本的嵌套急切加载操作相对较新。
我的设置方式是我有三个模型: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 我正在寻找一种方法来使用***权限目录进行嵌套急切加载查询,该目录将仅返回没有与给定用户关联的目录/权限。
【问题讨论】:
按照issue 中描述的一些方法,在尝试更直接地构建查询方面取得了一些进展。似乎 sequelize 在查询构建方面可能存在一些不足。 【参考方案1】:经过大量的互联网搜索和许多死胡同,我想我知道这个问题的不幸答案:sequelize 不擅长构建复杂的查询。
为了使我的问题更加清晰,mysql join types 的轮廓将我的场景描述为Anti Semi Join。
为了在 sequelize 中实现这个 sql 查询,我需要能够执行一个子查询,该子查询似乎不被 sequelize 原生支持(根据问题 #3961 缺乏移动来衡量)。
在 where 语句中使用 sequelize.literal
似乎可以很好地满足我的需求,但是如果 sequelize 从一开始就将所有连接类型合并到它们的功能中,而不是仅支持内部连接和左连接,那就太好了.对我来说似乎是一种疏忽。
【讨论】:
你有没有想出一些额外的东西?我正在寻找在eager nested
列上使用where
条件的方法。以上是关于Sequelize嵌套的渴望加载找到所有嵌套关联不匹配的地方的主要内容,如果未能解决你的问题,请参考以下文章