【问题标题】:JavaScript design pattern or node packages for nesting of de-normalized/flattened database query results用于嵌套非规范化/扁平化数据库查询结果的 JavaScript 设计模式或节点包
【发布时间】:2021-08-14 19:43:25
【问题描述】:

我对 NodeJS 有点陌生,并且使用 Javascripts 来解决这些类型的问题,所以感觉有点卡在这里。我正在使用具有相当典型的分层(即规范化)表/实体结构的传统关系数据库后端(Postgres)。我对 NodeJs 应用程序的要求之一是为一个页面(HTML 报告)提取数据,该页面基本上包含所有表格,但该页面还需要非常分层地显示数据。想象一下这样的查询结果:

[
{"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 等报告工具中)将更能代表实际的层次结构,因此我可以循环并创建嵌套的 <tables> 和/或 <divs>。像这样:

[
  {
    "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() 之类的操作或类似“normalizr”之类的包来重新构造数据。不过我对想法持开放态度。

我在array.reduce() 逻辑中迷失的地方是将代表父对象/实体的多个元素拉到更高级别。我认为这将是一个常见问题,但我似乎找不到使用array.reduce() 来执行此特定用例的人的示例。

【问题讨论】:

  • 我不认为有一个特殊的包可以做你想做的事,也许像 nodejs 中的 sequelize orm 这样的东西,但是要按摩你的数据,你不必让它异步,它可以在同步循环中完成。如果您使用 async 使用先前结果中的数据执行一个又一个查询,您始终可以使用新的 async await 语法像同步代码一样编写它,然后如果 nodejs 解释器是,则使用 babel 将其转换为您想要的 javascript 版本你的限制。

标签: javascript node.js json multidimensional-array data-structures


【解决方案1】:

这是一种方法:

const array = [
    {
        "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"
    }
];

const result = array.reduce((prev, curr) => {
    const company_found = prev.find(x => x.CompanyId === curr.CompanyId);
    if (!company_found) {
        prev.push({
            CompanyId: curr.CompanyId,
            CompanyType: curr.CompanyType,
            CompanyEmployees: curr.CompanyEmployees,
            Departments: [
                {
                    DepartmentId: curr.DepartmentId,
                    DepartmentName: curr.DepartmentName,
                    DepartmentEmployees: curr.DepartmentEmployees,
                    Employees: [
                        {
                            EmployeeId: curr.EmployeeId,
                            EmployeeName: curr.EmployeeName,
                            EmployeeHireDate: curr.EmployeeHireDate
                        }
                    ]
                }
            ]
        })
    }
    else {
        let department_found = company_found.Departments.find(x => x.DepartmentId === curr.DepartmentId);
        if (department_found) {
            department_found.Employees.push({
                EmployeeId: curr.EmployeeId,
                EmployeeName: curr.EmployeeName,
                EmployeeHireDate: curr.EmployeeHireDate
            });
        }
        else{
            company_found.Departments.push({
                DepartmentId: curr.DepartmentId,
                DepartmentName: curr.DepartmentName,
                DepartmentEmployees: curr.DepartmentEmployees,
                Employees: [
                    {
                        EmployeeId: curr.EmployeeId,
                        EmployeeName: curr.EmployeeName,
                        EmployeeHireDate: curr.EmployeeHireDate
                    }
                ]
            })
        }
    }

    return prev;
}, []);

console.log(JSON.stringify(result, null, 4));
const array = [
    {
        "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"
    }
];

const result = array.reduce((prev, curr) => {
    const company_found = prev.find(x => x.CompanyId === curr.CompanyId);
    if (!company_found) {
        prev.push({
            CompanyId: curr.CompanyId,
            CompanyType: curr.CompanyType,
            CompanyEmployees: curr.CompanyEmployees,
            Departments: [
                {
                    DepartmentId: curr.DepartmentId,
                    DepartmentName: curr.DepartmentName,
                    DepartmentEmployees: curr.DepartmentEmployees,
                    Employees: [
                        {
                            EmployeeId: curr.EmployeeId,
                            EmployeeName: curr.EmployeeName,
                            EmployeeHireDate: curr.EmployeeHireDate
                        }
                    ]
                }
            ]
        })
    }
    else {
        let department_found = company_found.Departments.find(x => x.DepartmentId === curr.DepartmentId);
        if (department_found) {
            department_found.Employees.push({
                EmployeeId: curr.EmployeeId,
                EmployeeName: curr.EmployeeName,
                EmployeeHireDate: curr.EmployeeHireDate
            });
        }
        else{
            company_found.Departments.push({
                DepartmentId: curr.DepartmentId,
                DepartmentName: curr.DepartmentName,
                DepartmentEmployees: curr.DepartmentEmployees,
                Employees: [
                    {
                        EmployeeId: curr.EmployeeId,
                        EmployeeName: curr.EmployeeName,
                        EmployeeHireDate: curr.EmployeeHireDate
                    }
                ]
            })
        }
    }

    return prev;
}, []);

console.log(JSON.stringify(result, null, 4));```

【讨论】:

    猜你喜欢
    • 2013-01-18
    • 2017-04-17
    • 2018-07-17
    • 1970-01-01
    • 1970-01-01
    • 2017-11-16
    • 1970-01-01
    • 2023-04-08
    • 2010-11-30
    相关资源
    最近更新 更多