【发布时间】:2022-06-10 17:37:30
【问题描述】:
假设我在一个表中有两条记录:
[
{
id: 1,
name: 'Michael',
associations: [
{
from: 1,
to: 2
}
]
},
{
id: 2,
name: 'John',
associations: [
{
from: 2,
to: 1
}
]
},
]
如果我克隆这两个对象,我需要得到以下结果:
[
{
id: 1,
name: 'Michael',
associations: [
{
from: 1,
to: 2
}
]
},
{
id: 2,
name: 'John',
associations: [
{
from: 2,
to: 1
}
]
},
{
id: 3,
name: 'Michael',
associations: [
{
from: 3,
to: 4
}
]
},
{
id: 4,
name: 'John',
associations: [
{
from: 4,
to: 3
}
]
},
]
我怎样才能有效地做到这一点?
我目前正在做的是循环浏览所有记录并为每个记录运行INSERT。对于每个元素,我跟踪它的oldId 和newId,然后,我查询具有这些newIds 之一的所有记录。然后,我替换了这些值。显然,这对于两条记录来说很好,但如果我有数千条记录需要克隆,每条记录都包含数千个关联,这会对性能造成很大影响。
这里是代码。函数cloneElements是发起者。
const updateElementAssociationsById = async ({ id, associations }) => {
return dbQuery(id, associations); // UPDATE ... SET associations WHERE id
}
const handleUpdateAssociations = async ({ data }) => {
const promises = [];
const records = await dbQuery(data.map(({ newId }) => newId)) ; // SELECT * FROM ... WHERE id in ANY
records.forEach(({ id, ...record }) => {
const associations = [];
record.associations.forEach((association) => {
const sourceElement = data.find(({ oldId }) => oldId === association.from);
const targetElement = data.find(({ oldId }) => oldId === association.to)
association.from = sourceElement.newId;
association.to = targetElement.newId;
associations.push(association);
});
promises.push(updateElementAssociationsById({ id, associations }))
});
await Promise.all(promises);
}
const createElement = async ({ element, data }) => {
const newElement = await dbQuery(element); // INSERT INTO ... RETURNING *;
data.push({
oldId: element.id,
newId: newElement.id,
});
}
const cloneElements = async (records) => {
const promises = [];
const data = [];
records.forEach((element) => {
promises.push(createElement({ element, records, data }));
});
await Promise.all(promises);
await handleUpdateAssociations({ data });
}
【问题讨论】:
-
您的问题是关于 JS 还是数据库?感觉好像少了一个标签。
-
我添加了我正在使用的数据库作为标签,但这主要是一个 JS 问题
-
请正确描述克隆逻辑。
-
我从现有实体中提取 id,然后创建具有完全相同属性的新实体(
id除外)。然后,我查询这些新创建的实体并根据data映射替换from和to值。
标签: javascript postgresql