Fix for not contains with all or - variety of changes needed to achieve the actual expected functionality.
This commit is contained in:
parent
1c44a9f0b8
commit
212b93cbe9
|
@ -236,6 +236,36 @@ export class QueryBuilder<T> {
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isMultiCondition() {
|
||||||
|
let count = 0
|
||||||
|
for (let filters of Object.values(this.query)) {
|
||||||
|
// not contains is one massive filter in allOr mode
|
||||||
|
if (typeof filters === "object") {
|
||||||
|
count += Object.keys(filters).length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count > 1
|
||||||
|
}
|
||||||
|
|
||||||
|
compressFilters(filters: Record<string, string[]>) {
|
||||||
|
const compressed: typeof filters = {}
|
||||||
|
for (let key of Object.keys(filters)) {
|
||||||
|
const finalKey = removeKeyNumbering(key)
|
||||||
|
if (compressed[finalKey]) {
|
||||||
|
compressed[finalKey] = compressed[finalKey].concat(filters[key])
|
||||||
|
} else {
|
||||||
|
compressed[finalKey] = filters[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// add prefixes back
|
||||||
|
const final: typeof filters = {}
|
||||||
|
let count = 1
|
||||||
|
for (let [key, value] of Object.entries(compressed)) {
|
||||||
|
final[`${count++}:${key}`] = value
|
||||||
|
}
|
||||||
|
return final
|
||||||
|
}
|
||||||
|
|
||||||
buildSearchQuery() {
|
buildSearchQuery() {
|
||||||
const builder = this
|
const builder = this
|
||||||
let allOr = this.query && this.query.allOr
|
let allOr = this.query && this.query.allOr
|
||||||
|
@ -272,9 +302,9 @@ export class QueryBuilder<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const notContains = (key: string, value: any) => {
|
const notContains = (key: string, value: any) => {
|
||||||
// @ts-ignore
|
const allPrefix = allOr ? "*:* AND " : ""
|
||||||
const allPrefix = allOr === "" ? "*:* AND" : ""
|
const mode = allOr ? "AND" : undefined
|
||||||
return allPrefix + "NOT " + contains(key, value)
|
return allPrefix + "NOT " + contains(key, value, mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
const containsAny = (key: string, value: any) => {
|
const containsAny = (key: string, value: any) => {
|
||||||
|
@ -299,21 +329,32 @@ export class QueryBuilder<T> {
|
||||||
return `${key}:(${orStatement})`
|
return `${key}:(${orStatement})`
|
||||||
}
|
}
|
||||||
|
|
||||||
function build(structure: any, queryFn: any) {
|
function build(
|
||||||
|
structure: any,
|
||||||
|
queryFn: (key: string, value: any) => string | null,
|
||||||
|
opts?: { returnBuilt?: boolean; mode?: string }
|
||||||
|
) {
|
||||||
|
let built = ""
|
||||||
for (let [key, value] of Object.entries(structure)) {
|
for (let [key, value] of Object.entries(structure)) {
|
||||||
// check for new format - remove numbering if needed
|
// check for new format - remove numbering if needed
|
||||||
key = removeKeyNumbering(key)
|
key = removeKeyNumbering(key)
|
||||||
key = builder.preprocess(builder.handleSpaces(key), {
|
key = builder.preprocess(builder.handleSpaces(key), {
|
||||||
escape: true,
|
escape: true,
|
||||||
})
|
})
|
||||||
const expression = queryFn(key, value)
|
let expression = queryFn(key, value)
|
||||||
if (expression == null) {
|
if (expression == null) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (query.length > 0) {
|
if (built.length > 0 || query.length > 0) {
|
||||||
query += ` ${allOr ? "OR" : "AND"} `
|
const mode = opts?.mode ? opts.mode : allOr ? "OR" : "AND"
|
||||||
|
built += ` ${mode} `
|
||||||
}
|
}
|
||||||
query += expression
|
built += expression
|
||||||
|
}
|
||||||
|
if (opts?.returnBuilt) {
|
||||||
|
return built
|
||||||
|
} else {
|
||||||
|
query += built
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,14 +425,14 @@ export class QueryBuilder<T> {
|
||||||
build(this.query.contains, contains)
|
build(this.query.contains, contains)
|
||||||
}
|
}
|
||||||
if (this.query.notContains) {
|
if (this.query.notContains) {
|
||||||
build(this.query.notContains, notContains)
|
build(this.compressFilters(this.query.notContains), notContains)
|
||||||
}
|
}
|
||||||
if (this.query.containsAny) {
|
if (this.query.containsAny) {
|
||||||
build(this.query.containsAny, containsAny)
|
build(this.query.containsAny, containsAny)
|
||||||
}
|
}
|
||||||
// make sure table ID is always added as an AND
|
// make sure table ID is always added as an AND
|
||||||
if (tableId) {
|
if (tableId) {
|
||||||
query = `(${query})`
|
query = this.isMultiCondition() ? `(${query})` : query
|
||||||
allOr = false
|
allOr = false
|
||||||
build({ tableId }, equal)
|
build({ tableId }, equal)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue