perf: Parse.Query.include now fetches pointers at same level in parallel (#9861)

This commit is contained in:
Antoine Cormouls
2025-11-17 15:42:49 +01:00
committed by GitHub
parent 52f7c89f3f
commit dafea21eb3
4 changed files with 279 additions and 81 deletions

View File

@@ -856,31 +856,54 @@ _UnsafeRestQuery.prototype.handleExcludeKeys = function () {
};
// Augments this.response with data at the paths provided in this.include.
_UnsafeRestQuery.prototype.handleInclude = function () {
_UnsafeRestQuery.prototype.handleInclude = async function () {
if (this.include.length == 0) {
return;
}
var pathResponse = includePath(
this.config,
this.auth,
this.response,
this.include[0],
this.context,
this.restOptions
);
if (pathResponse.then) {
return pathResponse.then(newResponse => {
this.response = newResponse;
this.include = this.include.slice(1);
return this.handleInclude();
const indexedResults = this.response.results.reduce((indexed, result, i) => {
indexed[result.objectId] = i;
return indexed;
}, {});
// Build the execution tree
const executionTree = {}
this.include.forEach(path => {
let current = executionTree;
path.forEach((node) => {
if (!current[node]) {
current[node] = {
path,
children: {}
};
}
current = current[node].children
});
} else if (this.include.length > 0) {
this.include = this.include.slice(1);
return this.handleInclude();
});
const recursiveExecutionTree = async (treeNode) => {
const { path, children } = treeNode;
const pathResponse = includePath(
this.config,
this.auth,
this.response,
path,
this.context,
this.restOptions,
this,
);
if (pathResponse.then) {
const newResponse = await pathResponse
newResponse.results.forEach(newObject => {
// We hydrate the root of each result with sub results
this.response.results[indexedResults[newObject.objectId]][path[0]] = newObject[path[0]];
})
}
return Promise.all(Object.values(children).map(recursiveExecutionTree));
}
return pathResponse;
await Promise.all(Object.values(executionTree).map(recursiveExecutionTree));
this.include = []
};
//Returns a promise of a processed set of results
@@ -1018,7 +1041,6 @@ function includePath(config, auth, response, path, context, restOptions = {}) {
} else if (restOptions.readPreference) {
includeRestOptions.readPreference = restOptions.readPreference;
}
const queryPromises = Object.keys(pointersHash).map(async className => {
const objectIds = Array.from(pointersHash[className]);
let where;
@@ -1057,7 +1079,6 @@ function includePath(config, auth, response, path, context, restOptions = {}) {
}
return replace;
}, {});
var resp = {
results: replacePointers(response.results, path, replace),
};