Commit d86abfde authored by Lauri Himanen's avatar Lauri Himanen
Browse files

Trying out new optimade query translation.

parent ce4e8cab
This diff is collapsed.
...@@ -81,9 +81,237 @@ class SearchBox{ ...@@ -81,9 +81,237 @@ class SearchBox{
} }
/**
* Given the final query, this function uses boolean algebra to reduce it
* into a flattened list of sets combined with AND or OR.
*/
reduceQuery(query, types) {
// For combining elements connected by AND into a list
function combineANDIn(query, types) {
const newQuery = []
const newTypes = []
for (let i=0; i < query.length;) {
const q1 = query[i];
const t1 = types[i];
const q2 = query[i+1];
const t2 = types[i+1];
const q3 = query[i+2];
const t3 = types[i+2];
if ((t1 === "E" || t1 === "EL" ) && (t3 === "E" || t3 === "EL" ) && q2 === "AND") {
let active = true
let elements = [q1, q3]
i = i + 3
while(active) {
const q4 = query[i];
const t4 = types[i];
const q5 = query[i+1];
const t5 = types[i+1];
if (q4 === "AND" && (t5 === "E" || t5 === "EL" )) {
elements.push(q5)
i += 2
} else {
active = false
newQuery.push(elements.join(", "))
newTypes.push("EL")
}
}
} else {
newQuery.push(q1)
newTypes.push(t1)
i += 1
}
}
return [newQuery, newTypes]
}
// For removing unnecessary quotes
function removeParenthesis(query, types) {
//console.log(query)
//console.log(types)
let removed = []
for (let i=0; i < query.length; ++i) {
const q1 = query[i];
const t1 = types[i];
if (q1 === "(") {
//console.log("Start found!")
let index = 0;
for (let j=i+1; j < query.length; ++j) {
const q2 = query[j];
const t2 = types[j];
if (q2 === "(") {
index += 1;
}
if (q2 === ")") {
//console.log("End found!")
if (index != 0) {
index -= 1;
} else {
const contents = query.slice(i+1, j)
//console.log("PARENTHESIS VALUES")
//console.log(contents)
//console.log(i+1, j)
const tp = types.slice(i+1, j)
//console.log("PARENTHESIS TYPES")
//console.log(tp)
let noop = true
for (let t of tp) {
if (t === "S") {
noop = false
break
}
}
if (noop) {
removed.push(j)
removed.push(i)
}
break
}
}
}
}
}
// Remove found parentheses
removed = removed.sort((a, b) => b - a);
//console.log(query.join(" "));
//console.log(removed);
for (let j=0; j < removed.length; ++j) {
query.splice(removed[j], 1);
types.splice(removed[j], 1);
}
//console.log(query.join(" "));
return [query, types]
}
// For combining elements connected by AND into a list
function combineANDOut(query, types) {
let newQuery = query
let newTypes = types
let combined = false
for (let i=0; i < query.length; ++i) {
// Look for AND surrounded by one or more parenthesis
const q1 = query[i];
const t1 = types[i];
const q2 = query[i+1];
const t2 = types[i+1];
const q3 = query[i+2];
const t3 = types[i+2];
if (q2 === "AND" && (q1 === ")" || q3 === "(" )) {
combined = true
// Get left hand and right hand side expressions
let lhsQ
let lhsT
let rhsQ
let rhsT
lhsQ = query.slice(0, i+1)
lhsT = types.slice(0, i+1)
if (q1 !== ")") {
lhsQ.unshift("(")
lhsT.unshift("P")
lhsQ.push(")")
lhsT.push("P")
}
rhsQ = query.slice(i+2, query.length)
rhsT = types.slice(i+2, query.length)
if (q3 !== "(") {
rhsQ.unshift("(")
rhsT.unshift("P")
rhsQ.push(")")
rhsT.push("P")
}
// Split the rhs into parts separated by OR
const rhsParts = []
let prevPos = 1
for (let j=1; j < rhsQ.length - 1; ++j) {
const sq1 = rhsQ[j];
if (sq1 === "OR") {
rhsParts.push([rhsQ.slice(prevPos, j), rhsT.slice(prevPos, j)])
prevPos = j+1
} else if (j === rhsQ.length - 2) {
rhsParts.push([rhsQ.slice(prevPos, j+1), rhsT.slice(prevPos, j+1)])
}
}
// Combine lhs with the different parts of rhs
let comboQ = []
let comboT = []
for (let j=0; j < rhsParts.length; ++j) {
let icomboQ = []
let icomboT = []
icomboQ = icomboQ.concat(rhsParts[j][0])
icomboT = icomboT.concat(rhsParts[j][1])
icomboQ.push("AND")
icomboT.push("S")
icomboQ = icomboQ.concat(lhsQ)
icomboT = icomboT.concat(lhsT)
if (j === 0) {
if (rhsParts.length > 1) {
comboQ.push("(")
comboT.push("P")
}
comboQ = comboQ.concat(icomboQ)
comboT = comboT.concat(icomboT)
if (rhsParts.length > 1) {
comboQ.push(")")
comboT.push("P")
}
} else {
comboQ.push("OR")
comboT.push("S")
comboQ.push("(")
comboT.push("P")
comboQ = comboQ.concat(icomboQ)
comboT = comboT.concat(icomboT)
comboQ.push(")")
comboT.push("P")
}
}
newQuery = comboQ
newTypes = comboT
break
}
}
return [newQuery, newTypes, combined]
}
// Merge
function merge(query, types) {
// Remove unnecessary parenthesis
[query, types] = removeParenthesis(query, types);
// Combined all elements connected with AND
[query, types] = combineANDIn(query, types);
// Combine parenthesis statements
let combined
[query, types, combined] = combineANDOut(query, types);
// If a combination was done, run recursively until no combination is
// done
if (combined) {
[query, types] = merge(query, types)
} else {
[query, types] = removeParenthesis(query, types);
[query, types] = combineANDIn(query, types);
}
return [query, types]
}
[query, types] = merge(query, types);
console.log(query.join(" "));
}
getOptimadeQuery(allowOtherElements){ getOptimadeQuery(allowOtherElements){
this.reduceQuery(this.searchQuery, this.queryTypes)
console.log('getOptimadeQuery this.searchQuery', this.searchQuery) console.log('getOptimadeQuery this.searchQuery', this.searchQuery)
if (this.searchQuery.length === 0 || if (this.searchQuery.length === 0 ||
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment