perf: Parse.Query.include now fetches pointers at same level in parallel (#9861)
This commit is contained in:
@@ -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),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user