javascript - 如何在 sequelize 中实现此 SQL 查询(多个连接和多个 AND/OR)

标签 javascript node.js postgresql sequelize.js

我一直在努力在 sequelize 中实现这个(在 SQL 语句下面)一段时间,但没有运气。我最初不得不进行单独的 sequelize 查询来获取数据,但这带来了很多限制。

    `SELECT "Documents".* FROM "Documents"
  INNER JOIN "AccessTypes"
    ON "AccessTypes"."id" = "Documents"."accessTypeId"
  INNER JOIN "Users"
    ON "Users"."id" = "Documents"."userId"
  INNER JOIN "Departments"
    ON "Departments"."id" = "Users"."departmentId"
  WHERE
    (("AccessTypes".name != 'private'
      AND "Departments"."id" = ${req.decoded.departmentId})
    OR "Users".id = ${req.decoded.id})
      AND ("Documents"."title" ILIKE '%${searchQuery}%'
        OR "Documents"."content" ILIKE '%${searchQuery}%'`

这是我得到的

    var dbQuery = {
    where: {
      $or: [
        {
          title: {
            $iLike: `%${searchQuery}%`
          }
        },
        {
          content: {
            $iLike: `%${searchQuery}%`
          }
        }
      ]
    },
    include: [{
      model: db.Users,
      where: { departmentId: req.decoded.departmentId }
    },
    {
      model: db.AccessTypes,
      where: { name: { $ne: 'private'}}
    }]
  };

  db.Documents.findAll(dbQuery)

我仍然需要根据提供的 userId 获取另一组文档。我觉得要走的路是在“$or”语句中执行“Include”。然而,到目前为止,我的研究让我相信这是不可能的。

这是我的模型 访问类型

export default (sequelize, DataTypes) => {
  const AccessTypes = sequelize.define('AccessTypes', {
    name: {
      type: DataTypes.STRING,
      allowNull: false,
      isUnique: true
    }
  }, {
    classMethods: {
      associate: (models) => {
        // associations can be defined here
        AccessTypes.hasMany(models.Documents, {
          foreignKey: 'accessTypeId',
          onDelete: 'CASCADE'
        });
      }
    }
  });
  return AccessTypes;
};

用户

export default (sequelize, DataTypes) => {
const Users = sequelize.define('Users', {
    username: {
      type: DataTypes.STRING,
      unique: true,
      allowNull: false
    },
    firstname: {
      type: DataTypes.STRING,
      allowNull: false
    },
    lastname: {
      type: DataTypes.STRING,
      allowNull: false
    },
    email: {
      type: DataTypes.STRING,
      unique: true,
      allowNull: false,
      validate: {
        isEmail: true
      }
    },
    password: {
      type: DataTypes.STRING,
      allowNull: false
    },
    roleId: {
      type: DataTypes.INTEGER,
      allowNull: false,
      defaultValue: 3
    },
    departmentId: {
      type: DataTypes.INTEGER,
      allowNull: false
    }
  }, {
    classMethods: {
      associate: (models) => {
        // associations defined here
        Users.belongsTo(models.Roles, {
          onDelete: 'CASCADE',
          foreignKey: 'roleId'
        });
        Users.belongsTo(models.Departments, {
          onDelete: 'CASCADE',
          foreignKey: 'departmentId'
        });

        Users.hasMany(models.Documents, {
          as: 'documents',
          foreignKey: 'userId',
          onDelete: 'CASCADE'
        });
      }
    }, ...

部门

export default (sequelize, DataTypes) => {
  const Departments = sequelize.define('Departments', {
    name: {
      type: DataTypes.STRING,
      allowNull: false,
      isUnique: true
    }
  }, {
    classMethods: {
      associate: (models) => {
        // associations can be defined here
        Departments.hasMany(models.Users, {
          foreignKey: 'departmentId',
          onDelete: 'CASCADE'
        });
      }
    }
  });
  return Departments;
};

和文件

export default (sequelize, DataTypes) => {
  const Documents = sequelize.define('Documents', {
    title: {
      type: DataTypes.STRING,
      allowNull: false
    },
    content: {
      type: DataTypes.TEXT,
      allowNull: false
    },
    userId: {
      type: DataTypes.INTEGER,
      allowNull: false
    },
    accessTypeId: {
      type: DataTypes.INTEGER,
      allowNull: false,
      defaultValue: 1
    },
    docTypeId: {
      type: DataTypes.INTEGER,
      allowNull: false
    }
  }, {
    classMethods: {
      associate: (models) => {
        // associations can be defined here
        Documents.belongsTo(models.Users, {
          foreignKey: 'userId',
          as: 'user',
          onDelete: 'CASCADE'
        });
        Documents.belongsTo(models.DocumentTypes, {
          foreignKey: 'docTypeId',
          onDelete: 'CASCADE'
        });
        Documents.belongsTo(models.AccessTypes, {
          foreignKey: 'accessTypeId',
          onDelete: 'CASCADE'
        });
      }
    }
  });
  return Documents;
};

任何指针将不胜感激 提前致谢

最佳答案

这是一个非常复杂的查询(当然是以 Sequelize 的方式),因此您需要以不同于以往的方式构建它。您应该使用类似 sequelize.col() 的函数, sequelize.where() , sequelize.or()sequelize.and() .此外,为了在查询中包含 Departments 模型,您需要在 findAll 查询的选项对象中使用嵌套的 include 语句。您可以根据需要嵌套包含项。

where: sequelize.and(
    sequelize.or(
        sequelize.and(
            sequelize.where(sequelize.col('AccessTypes.name'), '!=', 'private'),
            sequelize.where(sequelize.col('Departments.id'), '=', req.decoded.departmentId)
        ),
        sequelize.where(sequelize.col('Users.id'), '=', req.decoded.id)
    ),
    sequelize.or(
        { title: { $iLike: `%${searchQuery}%` } },
        { content: { $iLike: `%{searchQuery}%` } }
    )
),
include: [
    {
        model: db.Users,
        include: [ db.Departments ]
    },
    {
        model: db.AccessTypes
    }
]

您需要简要浏览一下上述功能的文档。简而言之,col() 根据模型名称和字段创建适当的列选择,where() 使用三个创建 WHERE 语句属性 - 列、条件(比较器)和逻辑,or() 创建OR 语句,and() 创建AND 声明。 or()and() 都可以获得多个参数,允许您创建复杂的语句,就像您的语句一样。

关于javascript - 如何在 sequelize 中实现此 SQL 查询(多个连接和多个 AND/OR),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42756968/

相关文章:

javascript - Node js从mongodb obejct内部值返回未定义

javascript - 为什么功能流程不正常?

postgresql - Postgresql 列出具有同一行值的性别类型

javascript - 带有 if 的球动画

jquery - 插入随机 <script> 以使用 $(document).ready(function()});在 Joomla

javascript - 在 NodeJS 中传递两个命令

ruby-on-rails - 通过 Rails 和 Postgresql 中对象的属性总和来限制查询

根据移动日期窗口有条件地求和的 SQL 查询

javascript - 回调函数中的 for 循环中的回调函数

javascript - 将 JQUERY 函数转换为原生 JavaScript