一个组织可以拥有多个 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
最佳答案
将逻辑移回到数据层的方法是使用 view或database 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/