summaryrefslogtreecommitdiff
path: root/pieces/suggest.js
diff options
context:
space:
mode:
authorGeorge Halkiadakis <gchalkiadakis@sklavenitis.co.gr>2024-04-10 03:41:05 +0300
committerGeorge Halkiadakis <gchalkiadakis@sklavenitis.co.gr>2024-04-10 03:41:05 +0300
commit0c65dee04506567ee50537ff2fbb83998b8fef0f (patch)
treeddeeaf79671b81254dc8960006adfb58016dfc25 /pieces/suggest.js
parented92bae9b662beba81889a62e29828302503fe8f (diff)
downloadoseine-0c65dee04506567ee50537ff2fbb83998b8fef0f.tar.gz
oseine-0c65dee04506567ee50537ff2fbb83998b8fef0f.tar.bz2
oseine-0c65dee04506567ee50537ff2fbb83998b8fef0f.zip
add methods in kb-util module; intoduce match-util module
Diffstat (limited to 'pieces/suggest.js')
-rw-r--r--pieces/suggest.js146
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);