我正在提取包含以下信息的数据库查询:
id、名称、roleId、roleTitle
在查询中,我正在提取用户及其 Angular 色。每个用户可以拥有 0 到 N 个 Angular 色。我希望最终有一个像这样的对象:
{
id
name
roles: [{
id
title
}]
}
最有效的方法是什么?目前我正在做这样的事情:
const data = [];
arr.forEach((u) => {
const index = data.findIndex(x => x.id === u.id);
if (index >= 0) {
data[index].roles.push({ id: u.roleId, title: u.roleTitle });
} else {
data.push({
id: u.id,
name: u.name,
roles: u.roleId ? [{
id: u.roleId,
title: u.roleTitle,
}] : [],
});
}
}
此解决方案工作正常,但不确定如果我们将用户数量扩展到 10k,每个用户的平均 Angular 色为 3 或 50k,每个用户有 5 个 Angular 色,这是否是完成此任务的最快方法
最佳答案
实际上,您最好的选择是在 SQL 中完成这一切,因为您正在使用 PostgreSQL 作为数据库(如评论中所述)。我不知道您的表和列的确切名称,因此您可能需要对此进行调整,但这将为您提供您想要的:
SELECT json_agg(t)
FROM (
SELECT
u.id,
u.name,
ro.roles
FROM "user" u
LEFT JOIN (
SELECT
ur.user_id,
json_agg(
json_build_object(
'id', r.id,
'title', r.title
)
) AS roles
FROM user_role ur
LEFT JOIN "role" r ON r.id = ur.role_id
GROUP BY ur.user_id
) ro ON ro.user_id = u.id
) t;
SQL fiddle :http://www.sqlfiddle.com/#!17/5f6ca/11
说明
json_build_object
将使用指定的名称/值对创建一个对象,因此:
json_build_object(
'id', r.id,
'title', r.title
)
将 Angular 色 id
和 title
组合成一个 JSON 对象,如下所示:
{id: 1, title: "Title 1"}
json_agg
将多行聚合到一个 JSON 数组中,因此它将上面的 Angular 色对象转换为单个列,该列是每个用户的 Angular 色对象数组(感谢内部子查询的 GROUP BY u.id
部分)。内部子查询给我们一个像这样的结果集(每个用户一行)
| user_id | roles |
|---------|------------------------------------------------------|
| 1 | [{id: 1, title: "Role 1"}, {id: 2, title: "Role 2"}] |
然后将子查询连接到用户表,所有这些都包装在另一个子查询中,以便可以在整个结果上使用 json_agg
并返回一个 json 对象,该对象是具有 Angular 色的用户数组。
关于javascript - 在javascript中将大量数据库结果转换为对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55718938/