node.js - Sequelize - 如何在嵌套关联中使用 where 子句?

标签 node.js postgresql express sequelize.js

我有一系列相互关联的 Sequelize 模型 -

  • UserInstitution ,它们都通过 EventInvitation 相关联。
  • UserInstitution 也通过 UserDetail 模型相互关联。

  • 我正在尝试查询一个事件并急切加载与其关联的所有机构。在急切加载机构时,我试图包括与该机构关联的用户,但我只想要也与该事件关联的用户。我尝试过类似下面的查询,但表示 '$events.id$': req.params.eventId 的 where 子句似乎不起作用 - 我在 Sequelize 的响应中不断收到 missing FROM-clause entry for table \"events\" 错误,但 Sequelize 给我的 SQL 输出中显然有一个 FROM \"Events\" AS \"Event\"它。

    有什么想法可以让这个查询工作吗?

    询问
    const event = await Event.findByPk(req.params.eventId, {
            include: [
              {
                model: Institution,
                as: 'institutions',
                attributes: ['id', 'name'],
                through: {
                  model: Invitation
                },
                include: [
                  {
                    model: User,
                    as: 'users',
                    where: {
                      '$events.id$': req.params.eventId
                    },
                    attributes: ['id', 'name'],
                    through: {
                      model: UserDetails,
                      attributes: []
                    },
                    include: [
                      {
                        model: Event,
                        as: 'events',
                        attributes: [],
                        through: {
                          model: Invitation,
                          attributes: []
                        }
                      }
                    ]
                  }
                ]
              }
            ]
          })
    

    楷模
    // user.js model
    User.belongsToMany(models.Institution, {
      through: models.UserDetails,
      as: 'institutions',
      foreignKey: 'userId',
      otherKey: 'institutionId'
    })
    
    User.belongsToMany(models.Event, {
      through: models.Invitation,
      as: 'events',
      foreignKey: 'userId',
      otherKey: 'eventId'
    })
    
    User.hasMany(models.Invitation, {
      as: 'invitations',
      foreignKey: 'userId'
    })
    
    // institution.js model
    
    Institution.belongsToMany(models.User, {
      through: models.UserDetails,
      as: 'users',
      foreignKey: 'institutionId',
      otherKey: 'userId'
    })
    
    Institution.belongsToMany(models.Event, {
      through: models.Invitation,
      as: 'events',
      foreignKey: 'institutionId',
      otherKey: 'eventId'
    })
    
    Institution.hasMany(models.Invitation, {
      as: 'invitations',
      foreignKey: 'institutionId'
    })
    
    // event.js modedl
    Event.belongsToMany(models.User, {
      through: models.Invitation,
      as: 'users',
      foreignKey: 'eventId',
      otherKey: 'userId'
    })
    
    Event.belongsToMany(models.Institution, {
      through: models.Invitation,
      as: 'institutions',
      foreignKey: 'eventId',
      otherKey: 'institutionId'
    })
    
    // invitation.js model
    Invitation.belongsTo(models.User, {
      foreignKey: 'userId',
       onDelete: 'CASCADE'
    })
    
    Invitation.belongsTo(models.Institution, {
      foreignKey: 'institutionId',
      onDelete: 'CASCADE'
    })
    

    SQL 输出
    SELECT
       \"Event\".\"id\",
       \"Event\".\"name\",
       \"Event\".\"date\",
       \"Event\".\"description\",
       \"Event\".\"venue\",
       \"Event\".\"type\",
       \"Event\".\"notes\",
       \"Event\".\"images\",
       \"Event\".\"createdAt\",
       \"Event\".\"updatedAt\",
       \"institutions\".\"id\" AS \"institutions.id\",
       \"institutions\".\"name\" AS \"institutions.name\",
       \"institutions -> Invitation\".\"id\" AS \"institutions.Invitation.id\",
       \"institutions -> Invitation\".\"eventId\" AS \"institutions.Invitation.eventId\",
       \"institutions -> Invitation\".\"userId\" AS \"institutions.Invitation.userId\",
       \"institutions -> Invitation\".\"institutionId\" AS \"institutions.Invitation.institutionId\",
       \"institutions -> Invitation\".\"paid\" AS \"institutions.Invitation.paid\",
       \"institutions -> Invitation\".\"status\" AS \"institutions.Invitation.status\",
       \"institutions -> Invitation\".\"createdAt\" AS \"institutions.Invitation.createdAt\",
       \"institutions -> Invitation\".\"updatedAt\" AS \"institutions.Invitation.updatedAt\",
       \"institutions -> users\".\"id\" AS \"institutions.users.id\",
       \"institutions -> users\".\"name\" AS \"institutions.users.name\",
       \"institutions -> users -> UserDetails\".\"id\" AS \"institutions.users.UserDetails.id\",
       \"institutions -> users -> UserDetails\".\"userId\" AS \"institutions.users.UserDetails.userId\",
       \"institutions -> users -> UserDetails\".\"institutionId\" AS \"institutions.users.UserDetails.institutionId\",
       \"institutions -> users -> UserDetails\".\"contactPoint\" AS \"institutions.users.UserDetails.contactPoint\",
       \"institutions -> users -> UserDetails\".\"createdAt\" AS \"institutions.users.UserDetails.createdAt\",
       \"institutions -> users -> UserDetails\".\"updatedAt\" AS \"institutions.users.UserDetails.updatedAt\",
       \"institutions -> users -> events -> Invitation\".\"id\" AS \"institutions.users.events.Invitation.id\",
       \"institutions -> users -> events -> Invitation\".\"eventId\" AS \"institutions.users.events.Invitation.eventId\",
       \"institutions -> users -> events -> Invitation\".\"userId\" AS \"institutions.users.events.Invitation.userId\",
       \"institutions -> users -> events -> Invitation\".\"institutionId\" AS \"institutions.users.events.Invitation.institutionId\",
       \"institutions -> users -> events -> Invitation\".\"paid\" AS \"institutions.users.events.Invitation.paid\",
       \"institutions -> users -> events -> Invitation\".\"status\" AS \"institutions.users.events.Invitation.status\",
       \"institutions -> users -> events -> Invitation\".\"createdAt\" AS \"institutions.users.events.Invitation.createdAt\",
       \"institutions -> users -> events -> Invitation\".\"updatedAt\" AS \"institutions.users.events.Invitation.updatedAt\" 
    FROM
       \"Events\" AS \"Event\" 
       LEFT OUTER JOIN
          (
    ( \"Invitations\" AS \"institutions -> Invitation\" 
             INNER JOIN
                \"Institutions\" AS \"institutions\" 
                ON \"institutions\".\"id\" = \"institutions -> Invitation\".\"institutionId\") 
             INNER JOIN
                (
                   \"UserDetails\" AS \"institutions -> users -> UserDetails\" 
                   INNER JOIN
                      \"Users\" AS \"institutions -> users\" 
                      ON \"institutions -> users\".\"id\" = \"institutions -> users -> UserDetails\".\"userId\"
                )
                ON \"institutions\".\"id\" = \"institutions -> users -> UserDetails\".\"institutionId\" 
                AND 
                (
                   \"institutions -> users\".\"deletedAt\" IS NULL 
                   AND \"events\".\"id\" = '1'
                )
             LEFT OUTER JOIN
                (
                   \"Invitations\" AS \"institutions -> users -> events -> Invitation\" 
                   INNER JOIN
                      \"Events\" AS \"institutions -> users -> events\" 
                      ON \"institutions -> users -> events\".\"id\" = \"institutions -> users -> events -> Invitation\".\"eventId\"
                )
                ON \"institutions -> users\".\"id\" = \"institutions -> users -> events -> Invitation\".\"userId\" 
          )
          ON \"Event\".\"id\" = \"institutions -> Invitation\".\"eventId\" 
          AND 
          (
             \"institutions\".\"deletedAt\" IS NULL
          )
    WHERE
       \"Event\".\"id\" = '1';
    

    最佳答案

    通常多对多关联是通过单独的查询获得的,这就是为什么您不能在父级别为子关联添加条件子句的原因。

    您可以使用 include 将条件移动到 model: Event ,但这样您就可以通过条件过滤事件的所有用户。我想这不是你想要达到的目标。

    您可以尝试在用户级别 where 上将 sequelize.literal 包含在过滤事件的子查询中,如下所示:

    model: User,
                    as: 'users',
                    where: sequelize.where(sequelize.literal('(EXISTS (SELECT 1 FROM Events e join Invitation i on <here is the rest of subquery>))'), true)
    

    关于node.js - Sequelize - 如何在嵌套关联中使用 where 子句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62303556/

    相关文章:

    ruby-on-rails - Rails 数据库,为什么在开发和生产中使用相同的 DBMS?

    php - PGSQL - 排序列时出现类型转换错误

    javascript - 当用户在命令提示符中选择任何字符串时,Node Js 不为任何请求服务

    javascript - 可以在 NodeJS/Javascript 中使用 while/for 循环将此递归代码编写为迭代代码吗

    node.js - 在 Node 上安装 Karma 时出错 - 检索当前目录时出错 - 在 OSX 上

    database - IMMUTABLE、STABLE 和 VOLATILE 关键字如何影响函数的行为?

    node.js - 应用程序为同一用户创建两个 session - Express js

    node.js - Mongoose : using promises as parameters for other functions

    node.js - 重用写入流而不结束它并一遍又一遍地声明新流

    javascript - fetch() header 显示为 application/x-www-form-urlencoded 而不是 application/json