Refactor expression to Mongo query translation
The previous approach was simplistic and could result in inefficient queries in certain edge cases, notably causing MongoDB to not utilize existing indexes when querying by last inform timestamps given upper and lower bounds. The new implementation leverages our existing expression minimizer code and can therefore generate more efficient queries or at least queries that can take advantage of existing indexes.
This commit is contained in:
1 parent
947f96299d
commit
3169e829e7
37 files changed
+2175
-1632
No files matched your search
+11
-22
@@ -18,13 +18,12 @@
|
||||
*/
|
||||
|
||||
import m, { ClosureComponent } from "mithril";
|
||||
import { parse, stringify, map } from "../lib/common/expression-parser";
|
||||
import { parse, stringify, map } from "../lib/common/expression/parser";
|
||||
import memoize from "../lib/common/memoize";
|
||||
import Autocomplete from "./autocomplete-compnent";
|
||||
import * as smartQuery from "./smart-query";
|
||||
import { filterToMongoQuery } from "../lib/mongodb-functions";
|
||||
import { validQuery } from "../lib/mongodb-functions";
|
||||
import { Expression } from "../lib/types";
|
||||
import { normalize } from "../lib/common/boolean-expression";
|
||||
|
||||
const getAutocomplete = memoize((resource) => {
|
||||
const labels = smartQuery.getLabels(resource);
|
||||
@@ -42,16 +41,6 @@ const getAutocomplete = memoize((resource) => {
|
||||
return autocomplete;
|
||||
});
|
||||
|
||||
function validateQuery(q: Expression): void {
|
||||
q = normalize(q);
|
||||
if (Array.isArray(q) && q[0] === "CASE") {
|
||||
q = q.slice(1).filter((a) => Array.isArray(a));
|
||||
if (q.length > 1) q = ["AND", ...q];
|
||||
else q = q[0];
|
||||
}
|
||||
if (Array.isArray(q)) filterToMongoQuery(q);
|
||||
}
|
||||
|
||||
function parseFilter(resource, f): Expression {
|
||||
let exp;
|
||||
if (/^[\s0-9a-zA-Z]+:/.test(f)) {
|
||||
@@ -62,16 +51,16 @@ function parseFilter(resource, f): Expression {
|
||||
exp = parse(f);
|
||||
}
|
||||
|
||||
const unpacked = map(exp, (e) => {
|
||||
if (Array.isArray(e) && e[0] === "FUNC") {
|
||||
if (e[1] === "Q") return smartQuery.unpack(resource, e[2], e[3]);
|
||||
else if (e[1] === "NOW") return Date.now();
|
||||
}
|
||||
return e;
|
||||
});
|
||||
|
||||
// Throws exception if invalid Mongo query
|
||||
validateQuery(
|
||||
map(exp, (e) => {
|
||||
if (Array.isArray(e) && e[0] === "FUNC") {
|
||||
if (e[1] === "Q") return smartQuery.unpack(resource, e[2], e[3]);
|
||||
else if (e[1] === "NOW") return Date.now();
|
||||
}
|
||||
return e;
|
||||
})
|
||||
);
|
||||
validQuery(unpacked, resource);
|
||||
|
||||
return exp;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user