【问题标题】:sequelize findandcountall function return same data when using paginationsequelize findandcountall 函数在使用分页时返回相同的数据
【发布时间】:2022-01-27 21:28:17
【问题描述】:

我正在使用sequelize: 6.9.0, sequelize-cli: ^6.3.0, express: 4.17.1, pg: 8.7.1

我在使用 sequelize findAndCountAll 时遇到问题,当我使用包含其他模型时,它会在我使用分页时返回相同的数据。

这是我的House Table代码

index: async (req, res) => {
    const { page, size, developer, city, priceone, pricetwo, project, isNew } =
      req.query;
    const { limit, offset } = getPagination(page, size);
    try {
      let filter = {};
      if (developer) {
        filter.developerId = developer;
      }
      if (city) {
        filter.cityId = city;
      }
      if (project) {
        filter.projectId = project;
      }
      if (isNew) {
        filter.isNew = isNew;
      }
      if (priceone && pricetwo) {
        const firstPrice = parseInt(priceone);
        const secondPrice = parseInt(pricetwo);
        if (firstPrice === 100000000 && secondPrice === 100000000) {
          filter.price = { [Op.lte]: firstPrice };
        } else if (firstPrice === 2000000000 && secondPrice === 2000000000) {
          filter.price = { [Op.gte]: firstPrice };
        } else {
          filter.price = { [Op.between]: [firstPrice, secondPrice] };
        }
      }
      const HousesData = await Houses.findAndCountAll({
        limit,
        offset,
        where: filter,
        attributes: [
          "id",
          "name",
          "description",
          "location",
          "price",
          "tanah",
          "bangunan",
          "lantai",
          "kamar_tidur",
          "kamar_mandi",
          "isNew",
        ],
        include: [
          { model: Developers, attributes: ["id", "name"] },
          { model: Cities, attributes: ["id", "name"] },
          { model: Projects, attributes: ["id", "name"] },
        ],
      });
      if (HousesData) {
        const response = getPagingData(HousesData, page, limit);
        res.status(200).json({
          status: "success",
          message: "Data Available",
          data: response,
        });
      } else {
        res.status(200).json({
          status: "success",
          message: "There is No Data",
          data: "No Data",
        });
      }
    } catch (error) {
      console.log(error);
      return next(
        new HttpError(
          "Something went wrong, could not get project.",
          500,
          error
        )
      );
    }
  }

我的分页功能

const getPagination = (page, size) => {
  const newPage = page ? page - 1 : 0;
  const limit = size ? +size : 10;
  const offset = newPage != 0 ? newPage * limit : 0;
  return { limit, offset };
};

const getPagingData = (data, page, limit) => {
  const { count: totalItems, rows: dataRows } = data;
  const currentPage = page ? +page : 1;
  const totalPages = Math.ceil(totalItems / limit);

  return { totalItems, totalPages, currentPage, dataRows };
};

module.exports = { getPagination, getPagingData };

假设我有 10 个数据 a,b,c,d,e,f,g,h,i,j

如果我看到第一页

http://localhost:3006/api/v1/house?size=5&page=1

它会返回 a,b,c,d,e(这是正确的)

如果我看到下一页

http://localhost:3006/api/v1/house?size=5&page=2

它会返回 e,d,c,b,a (只反向不显示 f,g,h,i,j)

如果我看到所有数据,它将返回正确的数据

http://localhost:3006/api/v1/house?size=10&page=1

它将返回 j,i,h,g,f,e,d,c,b,a

但如果我禁用了

include: [
  { model: Developers, attributes: ["id", "name"] },
  { model: Cities, attributes: ["id", "name"] },
  { model: Projects, attributes: ["id", "name"] },
],

使用分页时返回正确的数据。

House 的模型在这里

"use strict";
module.exports = {
  up: async (queryInterface, Sequelize) => {
    await queryInterface.createTable("Houses", {
      id: {
        allowNull: false,
        primaryKey: true,
        type: Sequelize.STRING(22),
      },
      name: {
        type: Sequelize.STRING,
      },
      projectId: {
        type: Sequelize.STRING(22),
        onDelete: "CASCADE",
        references: {
          model: "Projects",
          key: "id",
        },
      },
      cityId: {
        type: Sequelize.STRING(22),
        onDelete: "CASCADE",
        references: {
          model: "Cities",
          key: "id",
        },
      },
      developerId: {
        type: Sequelize.STRING(22),
        onDelete: "CASCADE",
        references: {
          model: "Developers",
          key: "id",
        },
      },
      description: {
        type: Sequelize.TEXT,
      },
      location: {
        type: Sequelize.STRING,
      },
      price: {
        type: Sequelize.BIGINT,
      },
      tanah: {
        type: Sequelize.INTEGER,
      },
      bangunan: {
        type: Sequelize.INTEGER,
      },
      lantai: {
        type: Sequelize.INTEGER,
      },
      kamar_tidur: {
        type: Sequelize.INTEGER,
      },
      kamar_mandi: {
        type: Sequelize.INTEGER,
      },
      house_thumbnail: {
        type: Sequelize.STRING,
      },
      isNew: {
        type: Sequelize.BOOLEAN,
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE,
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE,
      },
    });
  },
  down: async (queryInterface, Sequelize) => {
    await queryInterface.dropTable("Houses");
  },
};

我也在其他表上使用相同的分页方法。但其他表工作正常,只有这张表搞砸了。

另一个名为Project函数的表在这里供参考

index: async (req, res) => {
    const { page, size, developer, city, priceone, pricetwo } = req.query;
    const { limit, offset } = getPagination(page, size);
    try {
      let filter = { haveDeveloper: true };
      if (developer) {
        filter.developerId = developer;
      }
      if (city) {
        filter.cityId = city;
      }
      if (priceone && pricetwo) {
        const firstPrice = parseInt(priceone);
        const secondPrice = parseInt(pricetwo);
        if (firstPrice === 100000000 && secondPrice === 100000000) {
          filter.minPrice = { [Op.lte]: firstPrice };
        } else if (firstPrice === 2000000000 && secondPrice === 2000000000) {
          filter.minPrice = { [Op.gte]: firstPrice };
        } else {
          filter.minPrice = { [Op.between]: [firstPrice, secondPrice] };
        }
      }
      const projectsData = await Projects.findAndCountAll({
        limit,
        offset,
        where: filter,
        attributes: ["id", "name", "image", "location",'minPrice'],
        include: [
          { model: Cities, attributes: ["id", "name"] },
          { model: Developers, attributes: ["id", "name"] },
          { model: ProjectFacilities, attributes: ["facility"] },
        ],
      });
      if (projectsData) {
        const response = getPagingData(projectsData, page, limit);
        res.status(200).json({
          status: "success",
          message: "Data Available",
          data: response,
        });
      } else {
        res.status(200).json({
          status: "success",
          message: "There is No Data",
          data: "No Data",
        });
      }
    } catch (error) {
      console.log(error);
      return next(
        new HttpError(
          "Something went wrong, could not get project.",
          500,
          error
        )
      );
    }
  },

Project 模型

'use strict';
const {
  Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
  class Projects extends Model {
    /**
     * Helper method for defining associations.
     * This method is not a part of Sequelize lifecycle.
     * The `models/index` file will call this method automatically.
     */
    static associate(models) {
      // define association here
      Projects.belongsTo(models.Developers, { foreignKey: 'developerId' })
      Projects.belongsTo(models.Cities, { foreignKey: 'cityId' })
      Projects.hasMany(models.ProjectFacilities, { foreignKey: 'projectId' })
      Projects.hasMany(models.Houses, { foreignKey: 'projectId' })
    }
  };
  Projects.init({
    name: DataTypes.STRING,
    image: DataTypes.STRING,
    description: DataTypes.TEXT,
    location: DataTypes.STRING,
    minPrice:DataTypes.BIGINT,
    haveDeveloper: DataTypes.BOOLEAN,
    cityId: DataTypes.STRING,
    developerId: DataTypes.INTEGER
  }, {
    sequelize,
    modelName: 'Projects',
  });
  return Projects;
};

sequelize 为House page 1 生成 5 个数据的sql

SELECT "Houses"."id", "Houses"."name", "Houses"."description", "Houses"."location", "Houses"."price", "Houses"."tanah", "Houses"."bangunan", "Houses"."lantai", "Houses"."kamar_tidur", "Houses"."kamar_mandi", "Houses"."isNew", "Developer"."id" AS "Developer.id", "Developer"."name" AS "Developer.name", "City"."id" AS "City.id", "City"."name" AS "City.name", "Project"."id" AS "Project.id", "Project"."name" AS "Project.name" FROM "Houses" AS "Houses" LEFT OUTER JOIN "Developers" AS "Developer" ON "Houses"."developerId" = "Developer"."id" LEFT OUTER JOIN "Cities" AS "City" ON "Houses"."cityId" = "City"."id" LEFT OUTER JOIN "Projects" AS "Project" ON "Houses"."projectId" = "Project"."id" LIMIT 5 OFFSET 0;

sequelize 为Project page 1 生成 5 个数据的sql

SELECT "Projects".*, "City"."id" AS "City.id", "City"."name" AS "City.name", "Developer"."id" AS "Developer.id", "Developer"."name" AS "Developer.name", "ProjectFacilities"."id" AS "ProjectFacilities.id", "ProjectFacilities"."facility" AS "ProjectFacilities.facility" FROM (SELECT "Projects"."id", "Projects"."name", "Projects"."image", "Projects"."location", "Projects"."minPrice", "Projects"."cityId", "Projects"."developerId" FROM "Projects" AS "Projects" WHERE "Projects"."haveDeveloper" = true LIMIT 5 OFFSET 0) AS "Projects" LEFT OUTER JOIN "Cities" AS "City" ON "Projects"."cityId" = "City"."id" LEFT OUTER JOIN "Developers" AS "Developer" ON "Projects"."developerId" = "Developer"."id" LEFT OUTER JOIN "ProjectFacilities" AS "ProjectFacilities" ON "Projects"."id" = "ProjectFacilities"."projectId";

有什么解决办法吗?非常感谢大家的帮助和关注!

【问题讨论】:

  • 您是否尝试添加order?如果您使用limit/offset,则应使用order 以确保它限制了正确有序子集的记录。
  • 哦,谢谢您提供的信息。我已经尝试过了,它可以工作。不知道为什么只有那个表不起作用,而其他具有相同配置的表工作正常。谢谢!
  • 如果您与另一个表具有相同的配置,您可能希望该表也具有order。如果没有order,您可能会得到意想不到的结果,即使它碰巧现在正在工作,也不能保证它会继续工作。

标签: sql node.js postgresql express sequelize.js


【解决方案1】:

请尝试一下

const getPagination = (page = 1, size = 10) => {
    const offset = (page - 1) * size ;
    const limit = size ;
    return { limit, offset };
};

【讨论】:

    猜你喜欢
    • 2022-08-19
    • 2017-10-31
    • 2015-01-20
    • 1970-01-01
    • 2021-01-28
    • 2018-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多