diff options
Diffstat (limited to 'pieces/suggest.js')
| -rw-r--r-- | pieces/suggest.js | 146 |
1 files changed, 14 insertions, 132 deletions
diff --git a/pieces/suggest.js b/pieces/suggest.js index 9c37efb..ab62cfd 100644 --- a/pieces/suggest.js +++ b/pieces/suggest.js @@ -1,3 +1,8 @@ +const kb = require('./kb-util.js'); +const match = require('./match-util.js'); + +var n = 2; // Ngram base + /** (Search) SUGGESTIONS ENGINE * --------------------------------------------------------------------------- * @@ -79,97 +84,8 @@ function suggestions_module(options) { var keywordsURL = options.keywords_json; var cursor_on = { none: true }; // what product is highlighted; if not on product then { none: true } - - - - /** 2.PURIFY STRING FUNCTIONS - * ------------------------------------------------------------------------- - *////////////////////////////////////////////////////////////////////////// - - - /** keyboardize - * ------------------------------------------------------------------------- - * translates string to keyboard-latin keys - * (the ones that used whan typing each letter of the word) - * - * @param str (string): original string (utf8 of latin or greek subgroups) - * @return (string): latin/ascii equivalent string - */ - - // cache (keeo in global) any-character to keyboard-latin mapping - // --- -- -- - - - - var ORiGiNal = 'ςερτυθιοπασδφγηξκλζχψωβνμΕΡΤΥΘΙΟΠΑΣΔΦΓΗΞΚΛΖΧΨΩΒΝΜάέήίόύώϊΐϋΆΈΉΊΌΎΏΪΫQWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm0123456789- '.split(''); - var kbKeyZed = 'sertyuiopasdfghjklzxcvbnmertyuiopasdfghjklzxcvbnmaehioyviiyaehioyviyqwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnm0123456789- '.split(''); - const map = new Map(); - for (var i=0; i<ORiGiNal.length; i++) map.set(ORiGiNal[i], kbKeyZed[i]); - - // "keyboardize" function - // --- -- -- - - - - function keyboardize(str) { - str = str.replace('\'',''); - var out = ''; - // [map]'s implementation is 40x faster than [for]'s - for (var i=0 ; i< str.length; i++) out += map.get(str[i]); - return out; - } - - /** sanitize_GR - * ------------------------------------------------------------------------- - * replaces greek accended vowels with non accended ones - * takes care of sigma on the end of words - * - * @param str (string) - * @return sanitized string - */ - - // first cache (=create a global array) - // of accended to non-accended vowels mapping - // --- -- -- - - - - accented_vowels = []; - [ - 'ά α', 'έ ε', 'ή η', 'ί ι', 'ϊ ι', 'ΐ ι', 'ό ο', 'ύ υ', 'ϋ υ', 'ώ ω', - 'Ά Α', 'Έ Ε', 'Ή Η', 'Ί Ι', 'Ϊ Ι', 'Ό Ο', 'Ύ Υ', 'Ϋ Υ', 'Ώ Ω' - ].forEach( pair => { - ap = pair.split(' '); - accented_vowels.push({ - a: ap[0], // accented - p: ap[1] // pure = non accended - }); - }) - - // the actual `sanitize_GR` function code - // --- -- -- - - - - function sanitize_GR(str) { - - str = str.toLowerCase(); - - // replace accended vowels with pure ones - accented_vowels.forEach( v => { - str = str.replaceAll(v.a, v.p); - }); - - // replace sigma on the end of words - str = str + ' '; - str = str.replaceAll('σ-', 'ς-'); - str = str.replaceAll('σ ', 'ς '); - - return str; - } - - - /** clean text - * --- -- -- - - - - * removes non keyword characters [+ . , !] and internal multiple-spaces - * @param txt (string): product description - */ - function clean_text(txt) { - return txt.replace('+',' ').replace('.',' ').replace(',',' ') // change to space - .replace('!','').replace('\"', '') // remove character - .replace(' ',' ').replace(' ',' '); // remove multiple spaces - } - - + /** replaces (correcting descriptions) * == construct unequivocally liked words ////////////////////////////////// * ------------------------------------------------------------------------- @@ -262,7 +178,7 @@ function suggestions_module(options) { * mark linked words shall be handled as one-(key)word * also, edit common mistakes with suggested replaces * - * @param str + * @param str * @return */ function mark_explicit_links(str) { @@ -306,41 +222,6 @@ function suggestions_module(options) { } - /** Ngram fuzzy match algorithm - * (simple and fast) - */ - const createNgram = (word, n) => { // Ngram creation - if (word.length <3) return word; - const vector = []; - for (let i = 0; i < word.length-n+1; ++i) { - vector.push(word.slice(i, i + n)); - } - return vector; - }; - const checkSimilarity = (a, b) => { // Ngram match score - if (!_allowFuzzy) return 0; - - if (a.length > 0 && b.length > 0) { - const aNgram = createNgram(a, _Ngram_base); - const bNgram = createNgram(b, _Ngram_base); - let hits = 0; - for (let x = 0; x < aNgram.length; ++x) { - for (let y = 0; y < bNgram.length; ++y) { - if (aNgram[x] === bNgram[y]) { - hits += 1; - } - } - } - if (hits > 0) { - const union = aNgram.length + bNgram.length; - return (2.0 * hits) / union; - } - } - return 0; - }; - - - // Search Endine's match functions @@ -364,7 +245,8 @@ function suggestions_module(options) { chkArr.forEach( chk => { if (!found) { chk_kb = keyboardize(chk); - if ( (chk_kb.indexOf( query ) !== -1) || (fuzzy && (checkSimilarity(chk_kb, query) > _fuzzyLimit)) ) { + if ( (chk_kb.indexOf( query ) !== -1) + || (fuzzy && (match.similarity(chk_kb, query, n) > _fuzzyLimit)) ) { found = true; result = chk; } @@ -518,7 +400,7 @@ function suggestions_module(options) { if (qAr.length == 1) { // suggest 1st word ////////////////////// - var kbq = keyboardize(q); + var kbq = kb.keyboardize(q); // loop through root-words // ... to match all possible suggestions; @@ -547,14 +429,14 @@ function suggestions_module(options) { if (qAr.length == 2) { // suggest 2nd word ///////////////////////// root = qAr[0]; last = qAr[1]; - kbroot = keyboardize(root); - kblast = keyboardize(last); + kbroot = kb.keyboardize(root); + kblast = kb.keyboardize(last); // TODO: // change [_kwlinks.forEach] to for loop // --- - _kwlinks.forEach( it => { // locate the ... - if (is_exact_match(kbroot, it.w)) { // exact match of root-word + _kwlinks.forEach( it => { // locate the ... + if (match.exact(kbroot, kb.keyb_array(it.w))) { // exact match of root-word it.c.forEach ( wo => { // loop the word-links ... chk = check_match(kblast, wo.w, true); |
