Avoid multiple $nears in one query (#3798)

Mongo has a hard limit on 1 $near operation per query. Restructuring to
avoid SERVER-13732 should not invalidate a query by creating multiple
$near operations.

Additionally, queries with multiple $ors are now recursively handled,
whereas before, ops at the top level would only have been pushed one
level deeper.

https://github.com/parse-community/parse-server/issues/3767
This commit is contained in:
Jack Wearden
2017-05-10 05:32:08 -07:00
committed by Florent Vilmart
parent 64e6f40779
commit 7b9ebc4e8e
2 changed files with 34 additions and 1 deletions

View File

@@ -69,17 +69,27 @@ const validateQuery = query => {
* EG: {$or: [{a: 1}, {a: 2}], b: 2}
* Becomes: {$or: [{a: 1, b: 2}, {a: 2, b: 2}]}
*
* The only exceptions are $near and $nearSphere operators, which are
* constrained to only 1 operator per query. As a result, these ops
* remain at the top level
*
* https://jira.mongodb.org/browse/SERVER-13732
* https://github.com/parse-community/parse-server/issues/3767
*/
Object.keys(query).forEach(key => {
const noCollisions = !query.$or.some(subq => subq.hasOwnProperty(key))
if (key != '$or' && noCollisions) {
let hasNears = false
if (query[key] != null && typeof query[key] == 'object') {
hasNears = ('$near' in query[key] || '$nearSphere' in query[key])
}
if (key != '$or' && noCollisions && !hasNears) {
query.$or.forEach(subquery => {
subquery[key] = query[key];
});
delete query[key];
}
});
query.$or.forEach(validateQuery);
} else {
throw new Parse.Error(Parse.Error.INVALID_QUERY, 'Bad $or format - use an array value.');
}