accurate-search
Version:
The fastest and most accurate javascript full-text search library. Accurate search uses match distance algorithm to return the accurate order of the matching items.
1 lines • 2.68 kB
JavaScript
class AccurateSearch{constructor(){}addText(e,t,l=0){if(void 0===e)throw"id is a required parameter";let r=this.cleanupText(t);if(r.length>1e3){let e=r.lastIndexOf(" ",1e3);r=r.substr(0,e)}this.c||(this.c=[]),y({i:e,t:r},this.c);let i=r.split(" ");this.t||(this.t={d:{},i:[],n:{}}),l>1e3&&(l=1e3),l=Math.floor(l);for(let t of i){let i=this.t;for(var n=0;n<t.length;n++){let e=t.charAt(n);i.n[e]||(i.n[e]={d:{},i:[],n:{}}),i=i.n[e]}let h=1+r.indexOf(t);l&&(h+=l),i.d[e]?i.d[e]>h&&(i.d[e]=h):(i.d[e]=h,i.i.push(e))}}search(e){let t=this.accurateSearch(e);return 0==t.length&&(t=this.accurateSearch(this.fullCleanupText(e))),0==t.length&&(t=this.fuzzySearch(e)),t}accurateSearch(t){let l=this.cleanupText(t).split(" ");if(l=[...new Set(l)],!this.t)throw"There is no text added to search index";let r={},i={};for(let t of l)if(t){let l,n=this.t;for(l=0;l<t.length;l++){let e=n.n[t.charAt(l)];if(!e)break;n=e}l===t.length&&e(t,n,r,i,4)}let n={};for(let e in r){let t=r[e][0],l=r[e][1];n[t]||(n[t]={}),n[t][l]||(n[t][l]=[]),n[t][l].push(e)}let s=[];for(let e in n){let t=n[e];for(let e in t)h(s,t[e])}return s}fuzzySearch(e){let t=this.fullCleanupText(e);for(let l=e.length-1;l>=2;l--)t+=" "+e.substr(0,l);let l=t.split(" ").filter((e,t)=>e.length>1);return t=l.join(" "),this.accurateSearch(t)}suggestions(e,t){e=this.cleanupText(e);let l=[];for(let r of this.c){let i=r.t;if(i.length>e.length){let t=i.indexOf(e);if(t>=0&&(0===t||" "===i.charAt(t-1))){let r=i.indexOf(" ",t+e.length+1);i=r>0?i.substr(t,r-t):i.substr(t),i.length>e.length&&!l.includes(i)&&l.push(i)}}if(l.length>=t)break}return l.sort((e,t)=>e.length-t.length),l}remove(e){for(let t=0;t<this.c.length;t++)this.c[t].i===e&&this.c.splice(t,1);let t=this.t;if(t)for(let l in t.n)d(e,t.n[l])}cleanupText(e){return(e=e.replace(/<[^>]*>?/gm," ")).toLowerCase().replace(/[`~!%^*()_|=?;:",\.<>\{\}\[\]\\\/]/g," ").trim()}fullCleanupText(e){return(e=e.replace(/<[^>]*>?/gm," ")).toLowerCase().replace(/[^a-z0-9 ]/g," ").trim()}}function e(t,l,r,i,n){i[t]||(i[t]={});for(let e of l.i)if(!i[t][e]){i[t][e]=!0,r[e]||(r[e]=[],r[e][0]=1e5,r[e][1]=0);let h=n;r[e][0]-=h,r[e][1]+=l.d[e]}for(let h in l.n)e(t,l.n[h],r,i,n>1?n/2:1)}function d(e,t){let l=t.i.indexOf(e);l>=0&&t.i.splice(l,1),delete t.d[e];for(let l in t.n)d(e,t.n[l])}function y(e,t,l,r){var i=t.length,n=void 0!==l?l:0,h=void 0!==r?r:i-1,s=n+Math.floor((h-n)/2);0!=i?p(e,t[h])>=0?t.splice(h+1,0,e):p(e,t[n])<=0?t.splice(n,0,e):n>=h?t.splice(n,0,e):p(e,t[s])<=0?y(e,t,n,s-1):y(e,t,s+1,h):t.push(e)}function p(e,t){return e.r?t.r?t.r-e.r:-1:t.r?1:e.l-t.l}function h(e,t){let l=e.length,r=t.length;e.length+=r;for(let i=0;i<r;i++)e[l+i]=t[i]}module.exports=AccurateSearch;