Commit 64072257 authored by Iker Hurtado's avatar Iker Hurtado
Browse files

Implement Exclusive/Inclusive modes for both elements and formulas in a basic way

parent c98a54f4
Pipeline #90992 skipped with stage
......@@ -340,7 +340,8 @@ class NewSearchMod {
sendQuery(){
//**** The optimade query must be formed from the search box and the properties selected
let optimadeQuery = this.searchBox.getOptimadeQuery(true);//
const allowOtherElements = this.element.querySelector('#allow-other-elements').checked;
let optimadeQuery = this.searchBox.getOptimadeQuery(allowOtherElements);//
let optimadeQueryForProps = getOptimadeQueryFromProps(this.filterPanel.getValues());
if (optimadeQuery !== ''){ // if there are items in the serach box
optimadeQuery += (optimadeQueryForProps.length > 0 ? ' AND '+optimadeQueryForProps : '');
......
......@@ -94,23 +94,78 @@ class SearchBox{
let optimadeQuery = '';
//let otherElementsFlag = ( allowOtherElements ? '' : 'ONLY ' )
// Inclusive search
// Get the subqueries: parts of the query separated by ORs
const subqueries = [];
let currentSubquery = [];
subqueries.push(currentSubquery);
this.searchQuery.forEach( (item, i) => {
if (this.queryTypes[i] === 'E'){
optimadeQuery += ` elements HAS "${this.searchQuery[i]}"`
}else if ( this.queryTypes[i] === 'F' ){
if (this.searchQuery[i] === 'OR'){
currentSubquery = []; // new subquery
subqueries.push(currentSubquery);
}else
currentSubquery.push(item);
});
optimadeQuery += ` formula="${this.searchQuery[i]}"`
}else if ( this.queryTypes[i] === 'S' ){
optimadeQuery += ' '+this.searchQuery[i]+''
console.log("getOptimadeQuery subqueries: ", subqueries)
// Subqueries are either a formula or several elements separated by ANDs
subqueries.forEach( (subquery, i) => {
if (i > 0) optimadeQuery += ' OR '
if (allowOtherElements){ // Inclusive search
subquery.forEach( (item, i) => { // For every item in the subquery
if ( isElement(item) ){
optimadeQuery += ` elements HAS "${item}"`
}else if ( item === 'AND' || item === 'NOT'){
optimadeQuery += ' '+item+' ';
}else{ // Formula
let formula = new Formula(item);
optimadeQuery += formula.getOptimadeInclusiveSubquery();// optimadeQuery += ` formula="${this.searchQuery[i]}"`
}
});
}else{ // Exclusive search
if (subquery.length === 1 && !isElement(subquery[0])){ // Only one formula
optimadeQuery += `formula="${subquery[0]}"`;
}else{ // Several items, they all should be elements
optimadeQuery += getOptimadeExclusiveANDSubquery(subquery);
}
}
});
console.log('optimadeQuery: ', optimadeQuery)
//return 'elements HAS ONLY "F"';
return optimadeQuery;//'elements HAS ALL "Si", "Cl"';
return optimadeQuery;
function isElement(item){
return util.ELEMENTS.includes(item)
}
function getOptimadeExclusiveANDSubquery(subquery){ // this subquery is supposed to be form only for elements
let optSubquery = 'elements HAS ONLY ';
subquery.forEach( (item) => {
if (isElement(item)){//item !== 'AND'){ // check if element isntead ?
optSubquery += `"${item}",`;
}
});
optSubquery = optSubquery.substring(0, optSubquery.length-1);
return optSubquery;
}
}
......@@ -247,5 +302,117 @@ class SearchBox{
}
class Formula{
constructor(formula) {
this.formula = formula;
this.formulaMap = this._parseFormula(formula);
console.log('this.formulaMap: ', this.formulaMap);
}
_parseFormula(formula){
let index = 0;
let map = new Map();
let key;
while ( index < formula.length ){
let el2 = formula.substring(index, index+2);
let el1 = formula.substring(index, index+1);
if (util.ELEMENTS.indexOf(el2) >= 0){
map.set(el2, 1); // 1 default value
index += 2;
key = el2;
//console.log('eleemnt 2chars', key);
}else if (util.ELEMENTS.indexOf(el1) >= 0){
map.set(el1, 1); // 1 default value
index++;
key = el1;
//console.log('eleemnt 1chars', key);
}else{ // It's a number
let num = parseInt(el2);
if (num >= 10) index += 2; // 2 figures number
else index++;// 1 figure number
//console.log('number ', num, key);
map.set(key, num);
}
// console.log('FINAL LOOP', map, index);
}
return map;
}
getOptimadeInclusiveSubquery(){
let optSubquery = '';
let first = true;
this.formulaMap.forEach( (number, element)=> {
console.log(element, number);
if (first) first = false;
else optSubquery += ' AND ';
let token = element + (number === 1 ? '' : +number);
optSubquery += `formula CONTAINS "${token}"`;
});
return optSubquery;
}
/*
getReducedFormula(getTokens = true){
let counter = 0;
while ( !checkIfReduced(this.formulaMap) ){ // console.log('Reducing', this.formulaMap);
let div = 1;
if (isDivisibleBy(this.formulaMap, 2)) div = 2;
else if (isDivisibleBy(this.formulaMap, 3)) div = 3;
else if (isDivisibleBy(this.formulaMap, 5)) div = 5;
else if (isDivisibleBy(this.formulaMap, 7)) div = 7;
else if (isDivisibleBy(this.formulaMap, 11)) div = 11;
this.formulaMap.forEach( (value, key) => {
this.formulaMap.set(key, (value/div));
});
//console.log('Reducing DIV', this.formulaMap);
counter++;
if (counter > 5) break;
}
function checkIfReduced(formulaMap){
let min = 100;
formulaMap.forEach( (value, key) => {
if (value < min) min = value;
});
return min === 1;
}
function isDivisibleBy(formulaMap, n){
let div = true;
formulaMap.forEach( (value, key) => {
if (value % n !== 0) div = false;
});
return div;
}
let tokens = [];
let canonicalFormula = '';
if (getTokens){
this.formulaMap.forEach( (value, key) => tokens.push(key+value) );
}else{
let sortedElements = this._sortElements( Array.from( this.formulaMap.keys() ) );
sortedElements.forEach( element => {
canonicalFormula += element+this.formulaMap.get(element);
//canonicalFormula += element+(map.get(element) === 1 ? '' : map.get(element));
});
}
console.log('_reduceFormula RETURN: ', this.formulaMap, tokens, canonicalFormula);
return (getTokens ? tokens : canonicalFormula);
}
*/
}
// EXPORTS
module.exports = SearchBox;
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