node.js - Sequelize 将 JavaScript 逻辑移至数据库?

标签 node.js sequelize.js

一个组织可以拥有多个 field ,并且可用 field 的数量每天都会有所不同。
用户应该获得所有 field 的列表,无论它们在给定/指定的日期内是否可用。 将向用户显示的内容是,特定地点在给定日期内不可用。

Denoted by rest["available"] in the Code.

所以我在 javascript 中手动完成这项工作,我不能知道如何将 javascript 逻辑转移到 还拍 Sequelize ?这样它就会在响应中返回“可用”状态以及“平均”

实际上,我有大量数据,并且我相信在 JS 代码中循环并不是一种有效的方法。
因此,我认为必须将逻辑移至数据库,但我不确定是否使用 Sequelize 来完成此操作。

下面给出了数据库表、它们的关系和 JS 代码。

Organization.model.js

module.exports = function(sequelize, DataTypes) {
    let Organization = sequelize.define('Organization', {
        id: {
            type: DataTypes.INTEGER,
            autoIncrement: true,
            unique: true,
            allowNull: false
        },
        name: {
            type: DataTypes.STRING,
            primaryKey: true,
        }
    }, {
        timestamps: false,
        freezeTableName: true,
        tableName: "Organization",
        underscored: false
    });
    Organization.associate = function(models) {
        Organization.hasMany(models.Grounds, {
            onDelete: 'cascade',
            hooks: true,
            foreignKey: 'OrganizationName',
            sourceKey: 'name'
        });
    };
    return Organization;
};

Grounds.model.js

module.exports = function(sequelize, DataTypes) {
    let Grounds = sequelize.define('Grounds', {
        id: {
            type: DataTypes.INTEGER,
            autoIncrement: true,
            primaryKey: true
        },
        OrganizationName: {
            type: DataTypes.STRING,
            references: {
              model: 'Organization',
              key: 'name'
            }
        },
        NumbersAvailable: {
            type: DataTypes.INTEGER
        },
        Date: DataTypes.DATEONLY
    }, {
        timestamps: false,
        freezeTableName: true,
        tableName: "Grounds",
        underscored: false
    });
    Grounds.associate = function(models) {
        Grounds.belongsTo(models.Organization, {
            foreignKey: 'OrganizationName',
            targetKey: 'name'
        });
    };
    return Grounds;
};

JavaScript 逻辑:

//Get all the Grounds, in the specified Dates, e.g: '2018-05-01' & '2018-05-04'
let organizations = await Organization.findAll({
                        include: [
                            model: Grounds,
                            where: {
                                Date: {
                                    $gte: '2018-05-01',
                                    $lte: '2018-05-04'
                                } 
                            }
                        ]
                    });
//Calculate the Grounds Availability, in the specified Dates, e.g: '2018-05-01' & '2018-05-04'
let finalResult = organizations.map(function(currVal){
                        let organization = currVal.dataValues;
                        let {Grounds, ...rest} = organization;
                        rest["available"] = true;   //Custom Key.
                        rest["average"] = 0;    //Custom Key.
                        Grounds.forEach(function(ground){
                            let Date = ground.Date;
                            rest["average"] += ground.NumbersAvailable;
                            let number = ground.NumbersAvailable;
                            if(number == 0) rest["available"] = false;
                        });
                        rest["average"] = rest["average"]/Grounds.length;

                    });

示例表数据:
组织表:

id              name
---------------------------

1               authority1  
2               authority2
3               authority3 

理由表:

id     NumbersAvailable OrganizationName        Date              GroundName
----------------------------------------------------------------------------
1       5               authority1              2018-05-01          someName
2       3               authority1              2018-05-02          someName    
3       6               authority1              2018-05-03          someName
4       2               authority1              2018-05-04          someName    

5       7               authority2              2018-05-01          someName        
6       3               authority2              2018-05-02          someName
7       0               authority2              2018-05-03          someName
8       1               authority2              2018-05-04          someName


9       2               authority3              2018-05-01          someName
10      1               authority3              2018-05-02          someName    
11      3               authority3              2018-05-03          someName    
12      1               authority3              2018-05-04          someName

最佳答案

将逻辑移回到数据层的方法是使用 viewdatabase function (链接到 Postgres 文档;其他数据库可能使用“过程”而不是“函数”)。由于这里的具体情况涉及对所有组织及其基础运行一些简单的计算,因此使用 GROUP BY 连接这两个表的查询 View 和一些聚合就足够了。就 Sequelize 而言,您可以将 View 视为只读模型;每this issue ,唯一的问题是您无法同步它。

如果你正在做一些更复杂的事情,你将需要一个函数,这就是事情开始变得棘手的地方。如何实现函数取决于您所使用的 SQL 方言,因为每个数据库都有其自己的语言特性(SQL Server 使用 SELECT TOP n 而不是 SELECT .... LIMIT n,等等)。这就是您遇到第一个潜在问题的地方——您现在被锁定在一个数据库服务器上,无论是 Postgres、SQL Server 还是您拥有的其他数据库服务器。如果您想支持另一个数据库,您需要将您的函数移植到其方言中。

使用函数的第二个问题是,据我所知,Sequelize 没有提供一种简单的方法来执行返回表格结果的数据库函数 - 原因是它与其他对象关系映射器一样,抽象了方言等特殊性,并且只为您可以编写基本套件的 SELECT、INSERT 等语句提供接口(interface)。因此函数被忽略。为了执行一个,您需要使用它的 raw query功能。

关于node.js - Sequelize 将 JavaScript 逻辑移至数据库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50289645/

相关文章:

node.js - 引用尚未创建的模型,避免错误 : relation "TABLENAME" does not exist

mysql - 错误 : reference. 类 BelongsTo 扩展关联

node.js - 编译 Node 模块时 typescript 错误

sequelize.js - 如何通过表属性删除?

javascript - 我正在使用 readline 输入项目的数字,但无论我输入什么,它都会出现两次,即如果我按 1,则会出现 11 等

ruby - 由于 Nginx 是基于事件的服务器,Sleep 会停止 Nginx 吗?

javascript - Sequelize 与 PostgreSQL 的关系 (generator-sql-fullstack)

node.js - Sequelize reload() 清除所有模型数据

javascript - 如何制作不必要的文本Messenger bot Nodejs

node.js - 我如何在 CentOS 上知道当前有多少 Node 程序正在运行?