解析服务器编辑对象关系非常慢
Parse Server edit Relations on Object very slow
我得到了以下函数,它在 Parse Server 云代码上按预期工作,但速度慢得令人痛苦。
内部调用查询和保存函数的嵌套for
循环无疑是根本原因。
我如何重构这段代码,以便有一些异步处理,或者更好的是有什么方法可以删除/编辑对象上的关系,这方面的文档很差。
ClientLabels.applyClientLabels = async (req, res) => {
const { clients, labels } = req.params;
const user = req.user;
const objectIds = clients.map((client) => client.objectId);
const clientSaveList = [];
const clientClass = Parse.Object.extend('Clients');
const query = new Parse.Query(clientClass);
query.containedIn("objectId", objectIds);
const queryResult = await query.find({ sessionToken: user.getSessionToken() })
try {
for (const client of queryResult) {
const labelRelation = client.relation('labels');
const relatedLabels = await labelRelation.query().find({ sessionToken: user.getSessionToken() });
labelRelation.remove(relatedLabels);
for (const label of labels) {
label.className = "ClientLabels";
const labelRelationObj = Parse.Object.fromJSON(label)
labelRelation.add(labelRelationObj);
};
clientSaveList.push(client);
};
const saved = await Parse.Object.saveAll(clientSaveList, { sessionToken: user.getSessionToken() })
res.success(saved);
} catch (e) {
res.error(e);
};
}
一些奇怪的解释:
我不得不调用 Parse.Object.fromJSON
以使客户端标签对象成为 ParseObjectSubClass
并允许对其进行操作,例如添加关系。
您不能像使用指针那样在关系查询中使用 include,因此需要单独查询关系。排除了指针数组,因为将应用未知数量的标签。
有几件事可以做:(1) 在内循环中创建标签相对于外循环是不变的,因此可以在开始时一次性完成。 (2) 如果您只是要删除相关对象,则无需查询关系。使用 unset()
和 add 替换关系。 (3)这样不会节省多少计算量,但是clientSaveList
是多余的,我们可以直接保存查询结果...
ClientLabels.applyClientLabels = async (req, res) => {
const { clients, labels } = req.params;
const objectIds = clients.map((client) => client.objectId);
let labelObjects = labels.map(label => {
label.className = "ClientLabels";
return Parse.Object.fromJSON(label)
});
const query = new Parse.Query('Clients');
query.containedIn("objectId", objectIds);
const sessionToken = req.user.getSessionToken;
const queryResult = await query.find({ sessionToken: sessionToken })
try {
for (const client of queryResult) {
client.unset('labels');
client.relation('labels').add(labelObjects);
};
const saved = await Parse.Object.saveAll(queryResult, { sessionToken: sessionToken })
res.success(saved);
} catch (e) {
res.error(e);
};
}
我得到了以下函数,它在 Parse Server 云代码上按预期工作,但速度慢得令人痛苦。
内部调用查询和保存函数的嵌套for
循环无疑是根本原因。
我如何重构这段代码,以便有一些异步处理,或者更好的是有什么方法可以删除/编辑对象上的关系,这方面的文档很差。
ClientLabels.applyClientLabels = async (req, res) => {
const { clients, labels } = req.params;
const user = req.user;
const objectIds = clients.map((client) => client.objectId);
const clientSaveList = [];
const clientClass = Parse.Object.extend('Clients');
const query = new Parse.Query(clientClass);
query.containedIn("objectId", objectIds);
const queryResult = await query.find({ sessionToken: user.getSessionToken() })
try {
for (const client of queryResult) {
const labelRelation = client.relation('labels');
const relatedLabels = await labelRelation.query().find({ sessionToken: user.getSessionToken() });
labelRelation.remove(relatedLabels);
for (const label of labels) {
label.className = "ClientLabels";
const labelRelationObj = Parse.Object.fromJSON(label)
labelRelation.add(labelRelationObj);
};
clientSaveList.push(client);
};
const saved = await Parse.Object.saveAll(clientSaveList, { sessionToken: user.getSessionToken() })
res.success(saved);
} catch (e) {
res.error(e);
};
}
一些奇怪的解释:
我不得不调用 Parse.Object.fromJSON
以使客户端标签对象成为 ParseObjectSubClass
并允许对其进行操作,例如添加关系。
您不能像使用指针那样在关系查询中使用 include,因此需要单独查询关系。排除了指针数组,因为将应用未知数量的标签。
有几件事可以做:(1) 在内循环中创建标签相对于外循环是不变的,因此可以在开始时一次性完成。 (2) 如果您只是要删除相关对象,则无需查询关系。使用 unset()
和 add 替换关系。 (3)这样不会节省多少计算量,但是clientSaveList
是多余的,我们可以直接保存查询结果...
ClientLabels.applyClientLabels = async (req, res) => {
const { clients, labels } = req.params;
const objectIds = clients.map((client) => client.objectId);
let labelObjects = labels.map(label => {
label.className = "ClientLabels";
return Parse.Object.fromJSON(label)
});
const query = new Parse.Query('Clients');
query.containedIn("objectId", objectIds);
const sessionToken = req.user.getSessionToken;
const queryResult = await query.find({ sessionToken: sessionToken })
try {
for (const client of queryResult) {
client.unset('labels');
client.relation('labels').add(labelObjects);
};
const saved = await Parse.Object.saveAll(queryResult, { sessionToken: sessionToken })
res.success(saved);
} catch (e) {
res.error(e);
};
}