用于嵌套非规范化/扁平化数据库查询结果的JavaScript设计模式或节点包
我对NodeJS和使用Javascripts解决这些类型的问题有点陌生,所以我觉得这里有点卡住了。我正在使用一个传统的关系数据库后端(Postgres),它有一个相当典型的分层(即规范化的)表/实体结构。我对NodeJs应用程序的一个要求是为一个页面(HTML报告)提取数据,该页面基本上包含了所有表,但该页面也需要非常分层地显示数据。想象一下这样的查询结果:用于嵌套非规范化/扁平化数据库查询结果的JavaScript设计模式或节点包,javascript,node.js,json,multidimensional-array,data-structures,Javascript,Node.js,Json,Multidimensional Array,Data Structures,我对NodeJS和使用Javascripts解决这些类型的问题有点陌生,所以我觉得这里有点卡住了。我正在使用一个传统的关系数据库后端(Postgres),它有一个相当典型的分层(即规范化的)表/实体结构。我对NodeJs应用程序的一个要求是为一个页面(HTML报告)提取数据,该页面基本上包含了所有表,但该页面也需要非常分层地显示数据。想象一下这样的查询结果: [ {"CompanyId":1,"CompanyType":"Technology&q
[
{"CompanyId":1,"CompanyType":"Technology","CompanyEmployess":3000,"DepartmentId":12,"DepartmentName":"Analytics", "DepartmentEmployees":50, "EmployeeId":1234,"EmployeeName":"Fred","EmployeeHireDate":"2012-09-05"},
{"CompanyId":1,"CompanyType":"Technology","CompanyEmployess":3000,"DepartmentId":12,"DepartmentName":"Analytics", "DepartmentEmployees":50, "EmployeeId":145,"EmployeeName":"Joana","EmployeeHireDate":"2019-09-01"},
{"CompanyId":1,"CompanyType":"Technology","CompanyEmployess":3000,"DepartmentId":8,"DepartmentName":"Accounting", "DepartmentEmployees":25, "EmployeeId":1752,"EmployeeName":"Mary","EmployeeHireDate":"2020-08-01"},
{"CompanyId":1,"CompanyType":"Technology","CompanyEmployess":3000,"DepartmentId":8,"DepartmentName":"Accounting", "DepartmentEmployees":25, "EmployeeId":658,"EmployeeName":"Jose","EmployeeHireDate":"2018-12-01"},
{"CompanyId":1,"CompanyType":"Technology","CompanyEmployess":3000,"DepartmentId":1,"DepartmentName":"Executive", "DepartmentEmployees":4, "EmployeeId":9,"EmployeeName":"Maurice","EmployeeHireDate":"2011-10-01"}
]
但是,用于显示目的的最佳结构(在jsreport之类的报告工具中)将更能代表实际的层次结构,因此我可以循环并生成嵌套的
和/或
。像这样:
[
{
"CompanyId": 1,
"CompanyType": "Technology",
"CompanyEmployees": 3000,
"Departments": [
{
"DepartmentId": 12,
"DepartmentName": "Analytics",
"DepartmentEmployees": 50,
"Employees": [
{
"EmployeeId": 1234,
"EmployeeName": "Fred",
"EmployeeHireDate": "2012-09-05"
},
{
"EmployeeId": 145,
"EmployeeName": "Joana",
"EmployeeHireDate": "2019-09-01"
}
]
},
{
"DepartmentId": 8,
"DepartmentName": "Accounting",
"DepartmentEmployees": 25,
"Employees": [
{
"EmployeeId": 1752,
"EmployeeName": "Mary",
"EmployeeHireDate": "2020-08-01"
},
{
"EmployeeId": 658,
"EmployeeName": "Jose",
"EmployeeHireDate": "2018-12-01"
}
]
},
{
"DepartmentId": 1,
"DepartmentName": "Executive",
"DepartmentEmployees": 4,
"Employees": [
{
"EmployeeId": 9,
"EmployeeName": "Maurice",
"EmployeeHireDate": "2011-10-01"
}
]
}
]
}
]
我想继续在一个查询调用中提取数据,如图所示,并执行类似于array.reduce()
或类似于'normalizer'的包来重新构造数据。不过,我对想法持开放态度
我在数组中迷失了方向。reduce()
逻辑将表示父对象/实体的多个元素提升到更高级别。我认为这是一个常见的问题,但我似乎找不到使用array.reduce()
来执行此特定用例的示例。以下是一种方法:
const数组=[
{
“公司ID”:1,
“公司类型”:“技术”,
“公司雇员”:3000人,
“部门ID”:12,
“部门名称”:“分析”,
“部门员工”:50人,
“雇员ID”:1234,
“雇员姓名”:“弗雷德”,
“雇佣员工”:“2012-09-05”
},
{
“公司ID”:1,
“公司类型”:“技术”,
“公司雇员”:3000人,
“部门ID”:12,
“部门名称”:“分析”,
“部门员工”:50人,
“雇员ID”:145,
“员工姓名”:“Joana”,
“雇佣员工”:“2019-09-01”
},
{
“公司ID”:1,
“公司类型”:“技术”,
“公司雇员”:3000人,
“部门ID”:8,
“部门名称”:“会计”,
“部门员工”:25,
“雇员ID”:1752,
“雇员姓名”:“玛丽”,
“雇佣员工”:“2020-08-01”
},
{
“公司ID”:1,
“公司类型”:“技术”,
“公司雇员”:3000人,
“部门ID”:8,
“部门名称”:“会计”,
“部门员工”:25,
“雇员ID”:658,
“员工姓名”:“何塞”,
“雇佣员工”:“2018-12-01”
},
{
“公司ID”:1,
“公司类型”:“技术”,
“公司雇员”:3000人,
“部门ID”:1,
“部门名称”:“主管”,
“部门员工”:4,
“雇员ID”:9,
“雇员姓名”:“莫里斯”,
“雇佣员工”:“2011-10-01”
}
];
常量结果=数组。减少((上一个,当前)=>{
const company_found=prev.find(x=>x.CompanyId==curr.CompanyId);
如果(!找到公司){
上推({
公司ID:curr.CompanyId,
公司类型:当前公司类型,
公司雇员:当前公司雇员,
部门:[
{
部门ID:当前部门ID,
部门名称:当前部门名称,
部门员工:当前部门员工,
雇员:[
{
EmployeeId:curr.EmployeeId,
EmployeeName:curr.EmployeeName,
EmployeeHireDate:curr.EmployeeHireDate
}
]
}
]
})
}
否则{
让department\u found=company\u found.Departments.find(x=>x.DepartmentId==curr.DepartmentId);
如果(找到部门){
部门_found.Employees.push({
EmployeeId:curr.EmployeeId,
EmployeeName:curr.EmployeeName,
EmployeeHireDate:curr.EmployeeHireDate
});
}
否则{
公司/部门/推送({
部门ID:当前部门ID,
部门名称:当前部门名称,
部门员工:当前部门员工,
雇员:[
{
EmployeeId:curr.EmployeeId,
EmployeeName:curr.EmployeeName,
EmployeeHireDate:curr.EmployeeHireDate
}
]
})
}
}
返回上一个;
}, []);
log(JSON.stringify(result,null,4))代码>我不认为有一个特殊的包可以完全完成您想要做的事情,可能类似于nodejs中的sequelize orm,但是要处理数据,您不必使其异步,它可以在同步循环中完成。如果您使用async来执行一个又一个查询,并且使用以前结果中的数据,那么您可以始终使用新的async Wait语法将其像同步代码一样编写,然后使用babel将其转换为您想要的javascript版本(如果nodejs解释器是您的限制)。